Trying to Visualize Breath as a Line Graph

edited August 2016 in Library Questions

Hi all, I'm a noob.

I've got some JSON data from a device I wear that measures breathing. The file I reference in the code below is here.

And I've copied and pasted various bits of code from the Processing reference docs and also other sites to get to where I am now, which is code that parses the JSON and plots it on a graph, but right now it's only plotting one point. I know it's because I'm copying and pasting without really realizing the cause and effect, but I do believe I've actually learned a thing or two with that strategy over the last couple of days.

I've got a long way to go... like figuring out how to convert from Unix epoch to regular time, how to animate the line so it looks sorta like this EKG code, and how to only query the data for 24 hours at a time, etc. etc., but right now I'm just trying to figure out why I don't have a whole buncha dots plotted in that tiny space. Help?

// Importing Drawing Library from http://www.gicentre.net/utils/chart
import org.gicentre.utils.stat.*;

JSONObject json;
XYChart lineChart;

void setup() {
  size(500, 200);
  textFont(createFont("Arial", 10), 10);

  json = loadJSONObject("bigdata.json");

  JSONArray data = json.getJSONArray("data");

  for (int i = 0; i < data.size(); i++) {

    JSONObject item = data.getJSONObject(i); 

    int timestamp = item.getInt("timestamp");
    float value = item.getFloat("value");
    String event_type = item.getString("event_type");

    //println(timestamp + ", " + value + ", " + event_type);

    // Both x and y data set here.  
    lineChart = new XYChart(this);
    lineChart.setData(new float[] {timestamp}, 
      new float[] {value});

    // Axis formatting and labels.
    lineChart.showXAxis(true); 
    lineChart.showYAxis(true); 
    lineChart.setMinY(0);

    lineChart.setYFormat("00.00");  // Breath Rate
    lineChart.setXFormat("0000000000"); // EPOCH Timestamp Format

    // Symbol colours
    lineChart.setPointColour(color(180, 50, 50, 100));
    lineChart.setPointSize(5);
    lineChart.setLineWidth(2);
  }
}

void draw()
{
  background(255);
  textSize(9);
  lineChart.draw(15, 15, width-30, height-30);

  // Draw a title over the top of the chart.
  fill(120);
  textSize(20);
  text("Breath-rate", 70, 30);
  textSize(11);
  text(" Since Wearing Spire", 
    70, 45);
}

Answers

  • edited August 2016 Answer ✓

    Most of things you've placed inside your for ( ; ; ) {} loop shouldn't be there at all. :-SS

    For example @ line #26 lineChart = new XYChart(this);, you end up creating 6925 charts!!! @-)

    The trick is identify everything that wouldn't change inside the loop and place them outside.

    Another example: Should we state 6925 times that setYFormat() is "00.00"?

    In your case, the goal for the loop is extract both "timestamp" & "value" elements from "data" JSONArray.

    // forum.Processing.org/two/discussion/17883/
    // trying-to-visualize-breath-as-a-line-graph#Item_1
    
    // 2016-Aug-18
    
    import org.gicentre.utils.stat.XYChart;
    XYChart chart;
    
    void setup() {
      size(1300, 700);
      smooth(3);
      noLoop();
      fill(0100);
    
      textFont(createFont("Arial Bold", 9, true));
    
      chart = new XYChart(this);
    
      chart.showXAxis(true);
      chart.showYAxis(true);
      //chart.setMinY(0);
    
      chart.setYFormat("00.00"); // Breath Rate
      chart.setXFormat("0000000000"); // EPOCH Timestamp Format
    
      chart.setPointColour(color(180, 50, 50, 100));
      chart.setPointSize(3);
    
      chart.setLineColour(#0000FF);
      chart.setLineWidth(1.5);
    
      final JSONObject json = loadJSONObject("bigdata.json");
    
      final JSONArray data = json.getJSONArray("data");
      final int len = data.size();
      println(len);
    
      final float[] stamps = new float[len], vals = new float[len];
    
      for (int i = 0; i < len; ++i) {
        final JSONObject item = data.getJSONObject(i);
        stamps[i] = item.getInt("timestamp");
        vals[i] = item.getFloat("value");
      }
    
      chart.setData(stamps, vals);
    }
    
    void draw() {
      background(-1);
    
      textSize(9);
      chart.draw(15, 15, width-30, height-30);
    
      textSize(20);
      text("Breath-rate", 70, 30);
    
      textSize(11);
      text("Since Wearing Spire", 70, 45);
    }
    
  • :-O

    Well, redrawing the chart nearly 7k times might be a bit... inefficient.

    Thanks so much for the explanation and the working code. :)

  • edited August 2016

    You weren't drawing but instantiating ~7K XYChart objects!
    And likewise, ~16K float[] arrays w/ 1 length.
    And then passing just 1 "timestamp" & 1 "value" for each 1 via setData().
    In the end, only the last 6925th created XYChart stayed assigned to variable lineChart.
    And of course, w/ only 1 "timestamp" & 1 "value" in it to be graphed! :-\"

Sign In or Register to comment.