2-D Plotting component

Hello all,

I have been working on a plotting component during my parental leave for some of my upcoming projects. I hope someone else might be interested in using it. Link to the repo: GitHub - franshej/CustomMatPlot: Plot library for the JUCE Framework

Here are some of the features:

  • Axis scaling: Linear and logarithmic.
  • Customizable view using the lookandfeel class.
  • Legend.
  • Zoom.
  • Tracepoints.
  • Fill area between two graphs.
  • Axis labels.
  • Ticks and Tick-labels.
  • Grids and tiny grids.
  • Markers: Star, triangles, square etc.
  • Custom stroke path.
  • Callback for every visible data point.
  • Callback for tace points.
  • Two different downsampler levels

Best regards
Frans

19 Likes

Very nice looking project! Thanks for sharing!

1 Like

Yes very nice indeed :slight_smile:

How does it fair with realtime use?

1 Like

Thanks for the kind words

It may not be the best solution for real-time, but it works pretty well. There are two different types of downsampling modes. The first mode only looks at the given x-data and calculates which points need to be drawn, so there’s only one point drawn per column. In some real-time cases, we may only need to update the x-data ones, which means we only have to do this analysis once (And every time we resize or zoom in/out). After this analysis, we only need to update the y-data in real-time and calculate the new y-coordinate for the points we calculated earlier in the x-data analysis. The downside of this solution is that we discard points sharing the same column and lose accuracy in the plot. However, it doesn’t matter in some cases since the data is already smoothed. For example, a real-time frequency plot, where the x_data is static and y_data dynamic. Below is a short example:

// Setting the downsample type in the constructor. And deactivate auto lims.
Constructor() {
  m_plot.setDownsamplingType(cmp::DownsamplingType::x_downsaming);
  
  // Setting lims to deactivate the auto lims. 
  m_plot.xLim(1.0f, 10000.0f);
  m_plot.yLim(-40.0f, 10.0f);
}

// Setting the x_data
void prepareToPlay(int /*samplesPerBlockExpected*/,
                               double new_sample_rate) override {
  const auto x_data = createXDataFrom(new_sample_rate);

  // Setting the x_data once. Or.. every time we change sample_rate in this case.
  m_plot.plot(dummy_y_data, x_data);
}

// Only updates the y_data in cb.
void updateYDataCallBack(){
  m_plot->realtimePlot(new_y_data);
}

I’ve also updated the real-time plot example using the x_downsample: GitHub - franshej/Realtime-Frequency-Plot-Example: This is an example app for the CustomMatPlot Library.

The second downsampling mode analyses both the x/y-data to find the min/max points sharing the same column. This mode is, of course, slower than the first but you don’t lose any accuracy. This is also the default mode.

If you have any ideas on how can improve the real-time plot, please share :slight_smile:

2 Likes

Looks fantastic! Congratulations, and thanks for sharing :slight_smile:

1 Like

Looks great!

PS: I wish I had had that much free time during my own parental leave :laughing:

3 Likes