Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

In this Discussion

grafica library

2»

Comments

  • edited September 2015

    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

  • edited March 2016

    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 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 problem caused by layers drawing separately:

    Screenshot 2016-03-21 19.04.23 (2)

    The successful colour code plot:

    Screenshot 2016-03-21 19.04.40 (2)

  • edited March 2016

    Hi SamCE! You have various options. The easier one is to work with a single layer and use the setPointColors method:

    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
    
    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
      color[] pointColors = new color[numVal];
      for (int i=0; i < numVal; i++) {
        points.add(i, sensorVals[i]);
        if (sensorVals[i] < redBound) {
          pointColors[i] = color(255, 0, 0, 100);
        } 
        if (sensorVals[i] >= greenBound) {
          pointColors[i] = color(0, 255, 0, 100);
        } else {
          pointColors[i] = color(255, 800, 0, 100);
        }
      }
    
      //Plot Creation
      plot1.setPoints(points);
      plot1.setPointColors(pointColors); 
      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)
    } 
    

    I hope one of both methods works for you!

    And thank you for using the library :)

  • edited March 2016

    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!

  • edited October 2016

    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 have a problem to run this library on 2.2.1 unsupported class version can you help

  • edited November 2016

    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 **

    I never tried to make the library run on android mode.

    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

Sign In or Register to comment.