epezent / implot

Immediate Mode Plotting
MIT License
4.64k stars 516 forks source link

n00b q: How to properly use ImPlot to Plotline a changing value #459

Closed paulsammut closed 1 year ago

paulsammut commented 1 year ago

Hello! I'm creating this issue because after a fair bit of googling I couldn't find guidance on how to do this.

Context

I have an app that has some scalar variable that changes over time. I'd like to plot that variable as a line that changes over time over some period.

I ended up creating a vector of doubles of an acceptable size for my timeseries and I push in elements and delete from the front. I do this at a controlled number of times per second. I did this in the render loop for convenience and speed of getting this data plotted.

  static std::vector<double> frameRate(100, 0);
  static std::chrono::system_clock::time_point nextUpdate = clock::now() + 50ms;
  if (clock::now() > nextUpdate) {
    frameRate.push_back(ImGui::GetIO().Framerate);
    frameRate.erase(frameRate.begin());
    nextUpdate = std::chrono::system_clock::now() + 50ms;
  }
  if (ImPlot::BeginPlot("Framerate", ImVec2(-1, 0), ImPlotFlags_CanvasOnly)) {
    ImPlot::SetupAxes("Samples", "Framerate", ImPlotAxisFlags_AutoFit, ImPlotAxisFlags_AutoFit);
    ImPlot::PlotLine("", frameRate.data(), frameRate.size());
    ImPlot::EndPlot();
  }

This is not great because I'm touching each element in my timeseries on every insertion of a new number.

Questions

Q1: What is a convenient and rapid way of plotting a line (aka timeseries) from a from a scalar variable that is changing over time? Q2: Where is a good place to hold/create a timeseries for a scalar variable in my app for the sake of plotting it? Should it be in the core app itself (which I don't like because my core app is then forced to keep track of timeseries - which should be owned by the GUI/graphing portion of the code). Q3: What is an ideal container for this timeseries?

Thanks!

paulsammut commented 1 year ago

I used a deque that lets me push items in the back and pop front which worked well for me