I think it's compatible, but for some reason it doesn't pass the gui test... I have write the library guys to check which is the problem. Meanwhile you can install the lib as in the old times. Download the tar file from github, and copy the grafica directory into the processing library directory. The manual install in this link
https://github.com/processing/processing/wiki/How-to-Install-a-Contributed-Library
Firstly this library has been so useful to me, wonderful job! Secondly please instruct me if this should be posted elsewhere.
Ok so, I have been attempting to colour code a plotted array of data points depending on their value above the minimum in the set. I have put below the simplified version of my overall script that I have been using to create and prototype the process of the colour coding. I have managed to colour code the points depending on their value successfully but I have had to put them into different layers and this causes issues because I have not been able to find a way to merge the layers after plotting so that plot1.drawLines(); draws the lines correctly between the points, this also effects plot.drawFilledContours(GPlot.HORIZONTAL, 0); which I would also like to use.
The question is then, is there a way to either merge the layers after plotting so the lines draw correctly or is there a different method to colour code the data points that doesn't require them being in separate layers in the first place?
Any help with this would be gratefully received.
My Proto-Script:
import grafica.*;
String TitleText = ("Proto-Script");//Plot Title
float[] sensorVals = {27, 25, 23, 22, 21, 20, 20, 20, 21, 21.25, 21.5, 21.75, 22, 23, 24, 25, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 25, 24, 23, 22, 21.75, 21.5, 21.25, 21, 20, 20, 20, 21, 22, 23, 25, 27};//Sensor Readings Example
int numVal = sensorVals.length;//Length of Sensor Array for Plot Loop
float redVal = 1.6; //Red Colour Limit
float amberVal = 3; //Amber Colour Limit
GPlot plot1;
// Prepare the points
GPointsArray points = new GPointsArray(2000); //Amber Point Array
GPointsArray points1 = new GPointsArray(2000); // Red Point Array
GPointsArray points2 = new GPointsArray(2000); //Green Point Array
void setup() {
size(1900, 400); //Define Size of Plot
// Create the first plot
plot1 = new GPlot(this);
plot1.setPos(0, 0);
plot1.setMar(60, 70, 40, 70);
plot1.setDim(1703, 250);
plot1.setAxesOffset(4);
plot1.setTicksLength(4);
plot1.setTitleText("Testing - " + TitleText);
plot1.getYAxis().setAxisLabelText("Distance (mm)");
plot1.getXAxis().setAxisLabelText("Data Points");
//Array Colour Coding and Plotting------------------------------------
float minVal = min(sensorVals);//Find set minimum value
float redBound = (minVal+redVal);//Define Red Boundary
float greenBound = (minVal+amberVal);//Define Green Bondary
//For loop for sorting array values into appropriate layers
for (int i=0; i < numVal; i++) {
if (sensorVals[i] < redBound) {
points1.add(i, sensorVals[i]);
}
if (sensorVals[i] >= greenBound) {
points2.add(i, sensorVals[i]);
} else {
points.add(i, sensorVals[i]);
}
}
//Plot Creation
plot1.setPoints(points);
plot1.addLayer("redVal", points1); //Add red layer
plot1.addLayer("greenVal", points2); //Add green layer
plot1.setPointColor(color(255, 800, 0, 100)); //Set original layer amber
plot1.getLayer("redVal").setPointColor(color(255, 0, 0, 100)); //Set red layer red
plot1.getLayer("greenVal").setPointColor(color(0, 255, 0, 100));//Set green layer green
background(255);
// Draw the first plot
plot1.beginDraw();
plot1.drawBox();
plot1.drawXAxis();
plot1.drawYAxis();
plot1.drawTitle();
plot1.drawGridLines(GPlot.VERTICAL);
//plot1.drawFilledContours(GPlot.HORIZONTAL, 0);
plot1.drawPoints();
//plot1.drawLines();
plot1.endDraw();
plot1.activatePanning(); // Activate the panning (only for the first plot)
}
The other option, keeping your color and layer scheme, would be to add a new layer that includes all the points. We don't paint the points in that layer, but we use it to paint the lines and the contours. It's not that clean, but it works:
import grafica.*;
String TitleText = ("Proto-Script");//Plot Title
float[] sensorVals = {27, 25, 23, 22, 21, 20, 20, 20, 21, 21.25, 21.5, 21.75, 22, 23, 24, 25, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 25, 24, 23, 22, 21.75, 21.5, 21.25, 21, 20, 20, 20, 21, 22, 23, 25, 27};//Sensor Readings Example
int numVal = sensorVals.length;//Length of Sensor Array for Plot Loop
float redVal = 1.6; //Red Colour Limit
float amberVal = 3; //Amber Colour Limit
GPlot plot1;
// Prepare the points
GPointsArray points = new GPointsArray(2000); //Amber Point Array
GPointsArray points1 = new GPointsArray(2000); // Red Point Array
GPointsArray points2 = new GPointsArray(2000); //Green Point Array
GPointsArray allPoints = new GPointsArray(2000); //Green Point Array
void setup() {
size(1900, 400); //Define Size of Plot
// Create the first plot
plot1 = new GPlot(this);
plot1.setPos(0, 0);
plot1.setMar(60, 70, 40, 70);
plot1.setDim(1703, 250);
plot1.setAxesOffset(4);
plot1.setTicksLength(4);
plot1.setTitleText("Testing - " + TitleText);
plot1.getYAxis().setAxisLabelText("Distance (mm)");
plot1.getXAxis().setAxisLabelText("Data Points");
//Array Colour Coding and Plotting------------------------------------
float minVal = min(sensorVals);//Find set minimum value
float redBound = (minVal+redVal);//Define Red Boundary
float greenBound = (minVal+amberVal);//Define Green Bondary
//For loop for sorting array values into appropriate layers
for (int i=0; i < numVal; i++) {
allPoints.add(i, sensorVals[i]);
if (sensorVals[i] < redBound) {
points1.add(i, sensorVals[i]);
}
if (sensorVals[i] >= greenBound) {
points2.add(i, sensorVals[i]);
} else {
points.add(i, sensorVals[i]);
}
}
//Plot Creation
plot1.setPoints(points);
plot1.addLayer("redVal", points1); //Add red layer
plot1.addLayer("greenVal", points2); //Add green layer
plot1.addLayer("allVal", allPoints); //Add green layer
plot1.setPointColor(color(255, 800, 0, 100)); //Set original layer amber
plot1.getLayer("redVal").setPointColor(color(255, 0, 0, 100)); //Set red layer red
plot1.getLayer("greenVal").setPointColor(color(0, 255, 0, 100));//Set green layer green
background(255);
// Draw the first plot
plot1.beginDraw();
plot1.drawBox();
plot1.drawXAxis();
plot1.drawYAxis();
plot1.drawTitle();
plot1.drawGridLines(GPlot.VERTICAL);
plot1.getLayer("allVal").drawFilledContour(GPlot.HORIZONTAL, 0f);
plot1.getMainLayer().drawPoints();
plot1.getLayer("redVal").drawPoints();
plot1.getLayer("greenVal").drawPoints();
plot1.getLayer("allVal").drawLines();
plot1.endDraw();
plot1.activatePanning(); // Activate the panning (only for the first plot)
}
Hi Jagracar! The first method works perfectly and I have been able to introduce it to the larger script easily. The second method also shows me new ways to play with this library :D
Sorry to ask another question but how would I go about resetting the plot?
To remove layers from the plot you can use plot.removeLayer("layerId"). If you just want to update all the points in a layer you can use plot.getLayer("layerId").setPoints(points). If the points array is empty, this will clean the layer.
Hey jagracar! Thanks for the nice library. Is it compatible with Processing 2.x?? I can only seem to get it running with 3.x and I'm trying to use it alongside another library (ModelBuilder) which only compatible in 2.x. Thanks again - BillyB
Hi BillyB. Did you try older releases of the grafica? The differences with the current version are minimal (small bug fixes). You can download older releases from the github page:
https://github.com/jagracar/grafica/tree/master/releases
Cheers!
Is there any way to get grafica to display plots like logic signals? So basically connect the values with a line at the height of the previous value. I have looked into the reference, but it does not says much to me. I tried drawing simply lines, but can not managed to get it showing on my plot.
Win10, Processing 3.2.1 or 3.1.2 + Android mode 3.0.1 or 4.0 b2
grafica.jar -> grafica-a0623d69ef03e1db052e333c71774ffa.jar
[dx]
[dx] UNEXPECTED TOP-LEVEL EXCEPTION:
[dx] java.lang.RuntimeException: Exception parsing classes
[dx] at com.android.dx.command.dexer.Main.processClass(Main.java:752)
[dx] at com.android.dx.command.dexer.Main.processFileBytes(Main.java:718)
[dx] at com.android.dx.command.dexer.Main.access$1200(Main.java:85)
[dx] at com.android.dx.command.dexer.Main$FileBytesConsumer.processFileBytes(Main.java:1645)
[dx] at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
[dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
[dx] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
[dx] at com.android.dx.command.dexer.Main.processOne(Main.java:672)
[dx] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:574)
[dx] at com.android.dx.command.dexer.Main.runMonoDex(Main.java:311)
[dx] at com.android.dx.command.dexer.Main.run(Main.java:277)
[dx] at com.android.dx.command.dexer.Main.main(Main.java:245)
[dx] at com.android.dx.command.Main.main(Main.java:106)
[dx] Caused by: com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)
[dx] at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)
[dx] at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)
[dx] at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)
[dx] at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)
[dx] at com.android.dx.command.dexer.Main.parseClass(Main.java:764)
[dx] at com.android.dx.command.dexer.Main.access$1500(Main.java:85)
[dx] at com.android.dx.command.dexer.Main$ClassParserTask.call(Main.java:1684)
[dx] at com.android.dx.command.dexer.Main.processClass(Main.java:749)
[dx] ... 12 more
[dx] 1 error; aborting
BUILD FAILED
I'm having trouble finding the index of a returned GPoint from any layer.
I'm attempting to implement a scrubber like feature where I can set a starting position anywhere on the line graph to read from, akin to skipping ahead in a video player like Quicktime.
My first thought was to try access the "points" variable of GPointsArray, but realized it's private. Is there a method I'm missing that will return the index of a GPoint?
So far this library has saved me a TON of time and is incredibly feature rich. I'm just a little stuck on this one feature!
There are however some public methods in GPlot that might be useful.
You could use the getPoints() or the getPointsRef() methods to get a copy or the reference of the GPoint arrays for a given layer.
Or you could use the getPlotPosAt() GPlot method to calculate the position of a point in the screen, relative to the plot reference system, and then give this position to the getPointIndexAtPlotPos() GLayer method to get the point index at that screen position. See for example this code that removes points under the cursor:
I just wanted to let you know that, together with the Processing and p5.js versions, there is now available an openFramewors (C++) version of the library:
Comments
thank you jagracar. I made the legend by ellipse() and text() functions. May be, will be helpful for someone:
` void makeLegend() { String[] legendText = legendText(); float[] legendX = legendX(); float[] legendY = legendY(); color[] legendColor = legendColor(); textSize(14);
for (int i = 0; i < legendText.length; i++) { fill(legendColor[i]); stroke(legendColor[i]); ellipse(legendX[i], legendY[i], 10, 10); text(legendText[i], legendX[i] + 10, legendY[i]+5); } } `
Make your own functions to define legendText, legendX etc.
Hi @jagracar.
Any hope for a new version of grafica to be compatible with Processing 3.0?
I think it's compatible, but for some reason it doesn't pass the gui test... I have write the library guys to check which is the problem. Meanwhile you can install the lib as in the old times. Download the tar file from github, and copy the grafica directory into the processing library directory. The manual install in this link https://github.com/processing/processing/wiki/How-to-Install-a-Contributed-Library
Hi,
Firstly this library has been so useful to me, wonderful job! Secondly please instruct me if this should be posted elsewhere.
Ok so, I have been attempting to colour code a plotted array of data points depending on their value above the minimum in the set. I have put below the simplified version of my overall script that I have been using to create and prototype the process of the colour coding. I have managed to colour code the points depending on their value successfully but I have had to put them into different layers and this causes issues because I have not been able to find a way to merge the layers after plotting so that
plot1.drawLines();
draws the lines correctly between the points, this also effectsplot.drawFilledContours(GPlot.HORIZONTAL, 0);
which I would also like to use.The question is then, is there a way to either merge the layers after plotting so the lines draw correctly or is there a different method to colour code the data points that doesn't require them being in separate layers in the first place?
Any help with this would be gratefully received.
My Proto-Script:
The problem caused by layers drawing separately:
The successful colour code plot:
Hi SamCE! You have various options. The easier one is to work with a single layer and use the setPointColors method:
The other option, keeping your color and layer scheme, would be to add a new layer that includes all the points. We don't paint the points in that layer, but we use it to paint the lines and the contours. It's not that clean, but it works:
I hope one of both methods works for you!
And thank you for using the library :)
Hi Jagracar! The first method works perfectly and I have been able to introduce it to the larger script easily. The second method also shows me new ways to play with this library :D
Sorry to ask another question but how would I go about resetting the plot?
Thankyou so much for your time and help.
To remove layers from the plot you can use plot.removeLayer("layerId"). If you just want to update all the points in a layer you can use plot.getLayer("layerId").setPoints(points). If the points array is empty, this will clean the layer.
Have fun with the library!
Thankyou again!
Hey jagracar! Thanks for the nice library. Is it compatible with Processing 2.x?? I can only seem to get it running with 3.x and I'm trying to use it alongside another library (ModelBuilder) which only compatible in 2.x. Thanks again - BillyB
Hi! you can download now the grafica library in Processing 3.1 using the contribution manager. It's no longer showing as incompatible.
Hi BillyB. Did you try older releases of the grafica? The differences with the current version are minimal (small bug fixes). You can download older releases from the github page: https://github.com/jagracar/grafica/tree/master/releases Cheers!
Hello!
Is there any way to get grafica to display plots like logic signals? So basically connect the values with a line at the height of the previous value. I have looked into the reference, but it does not says much to me. I tried drawing simply lines, but can not managed to get it showing on my plot.
Hi moderboy. Can you show me an screenshot from other software that can do it. I don't understand what you want to do. Thanks!
Win10, Processing 3.2.1 or 3.1.2 + Android mode 3.0.1 or 4.0 b2
I have a problem to run this library on 2.2.1 unsupported class version can you help
Hi dehicka, I never tried to make the library run on android mode. I think you should ask the android mode developers to solve your problem.
Ahmad, I had to make some changes in the library to make it compatible with processing 3. You can try with older versions of the library:
https://github.com/jagracar/grafica/tree/master/releases
I think grafica-4.zip should work with Processing 2.
Hi, thanks for thit usefull library. One question is it posibble only zoom in one axis? Leave the y-axis locked and zoom only on the x-axis. Thanks
thank you so much.. actually grafica-3.zip work
**jagracar **
Funny, I was using it in android mode witout a problem since android mode was first introduced in processing. Damn.
Digging up this old thread...
I'm having trouble finding the index of a returned GPoint from any layer.
I'm attempting to implement a scrubber like feature where I can set a starting position anywhere on the line graph to read from, akin to skipping ahead in a video player like Quicktime.
My first thought was to try access the "points" variable of GPointsArray, but realized it's private. Is there a method I'm missing that will return the index of a GPoint?
So far this library has saved me a TON of time and is incredibly feature rich. I'm just a little stuck on this one feature!
Hi wizink,
I'm afraid I didn't plan for a method for that...
There are however some public methods in GPlot that might be useful. You could use the getPoints() or the getPointsRef() methods to get a copy or the reference of the GPoint arrays for a given layer.
https://github.com/jagracar/grafica/blob/master/src/grafica/GPlot.java#L2538
Or you could use the getPlotPosAt() GPlot method to calculate the position of a point in the screen, relative to the plot reference system, and then give this position to the getPointIndexAtPlotPos() GLayer method to get the point index at that screen position. See for example this code that removes points under the cursor:
https://github.com/jagracar/grafica/blob/master/src/grafica/GPlot.java#L421
I hope it helps!
Hi!
I just wanted to let you know that, together with the Processing and p5.js versions, there is now available an openFramewors (C++) version of the library:
https://github.com/jagracar/ofxGrafica
I hope it's helpful for some of you.
Cheers! javier