ocornut/imgui

ImPlot - An Advanced 2D Plotting API

epezent opened this issue · 17 comments

Previously, I posted a prototype 2D plotting widget here. It was well received, and many of you provided great feedback and ideas. Since then, I've been refining and improving the API to appeal to the broader ImGui audience. It has reached an solid "alpha" stage which I think is ready to share. The library, feature list, and demo can be found in the following repository:

ImPlot

ImPlot
ImPlot

Notable API Improvements and Additions

  • The previous implementation burdened users with state-management, requiring user-owned structs for both plots and plot items. This has been completely eliminated in favor of a more ImGui-like interface. All plot state is managed internally, and the API is modeled after the conventional Begin/End approach. Overall, this means the API is incredibly simple to use:
if (ImGui::BeginPlot("My Plot")) {
    ImGui::Plot("My Line Plot", x_data, y_data, 1000);
    ImGui::PlotBar("My Bar Plot", values, 10);
    ...
    ImGui::EndPlot();
}
  • Like ImGui, widget customization and configuration is accomplished through optional arguments, flags, preceding function calls, and a stack based styling approach:
ImPlotFlags p_flgs = ImPlotFlags_Legend    | ImPlotFlags_AntiAliased;
ImAxisFlags x_flgs = ImAxisFlags_GridLines | ImAxisFlags_LogScale;
ImAxisFlags y_flgs = ImAxisFlags_GridLines | ImAxisFlags_TickLabels;

ImGui::SetNextPlotRange(0.01, 10000, -50, 50, ImGuiCond_Always);
if (ImGui::BeginPlot("Bode Plot", "rad/s", "dB", ImVec2(400,300), p_flgs, x_flgs, y_flgs)) {
    ImGui::PushPlotStyleVar(ImPlotStyleVar_Marker, ImMarker_Circle);
    ImGui::Plot("Signal 1", t, s1, 100);
    ImGui::PushPlotStyleVar(ImPlotStyleVar_Marker, ImMarker_Square);
    ImGui::Plot("Signal 2", t, s2, 100);
    ImGui::PushPlotStyleVar(ImPlotStyleVar_Marker, ImMarker_Diamond);
    ImGui::Plot("Signal 3", t, s3, 100);
    ImGui::PopPlotStyleVar(3);
    ImGui::EndPlot()
}
  • Similar to ImGui::PlotLines, plot functions take raw pointers to data which can be used with a stride value to handle arbitrary data alignment. Also, custom data "getters" can be used for more advanced scenarios.
  • The previous implementation used C++ STL containers (vector, string). Now, the library uses only data structures from imgui_internal.h and has eliminated all C++ headers/features that ImGui was not already using. This should make it easier to integrate with other languages.
  • In addition to retaining all previous features, other new features include:
    • logarithmic axes scaling
    • error bars
    • customizable data markers
    • customizable color palettes
    • improved plot context menu
    • text labels and callouts can be added to the plot area

Roadmap and Contributing

My current plan for this library is as follows:

  • To support as many plot types as possible, within reason (i.e. box-plots and stem-plots seem like a reasonable addition, but contours, heat maps, and 3D plots will likely not be feasible with the current ImGui drawing functions)
  • Expand the set of utility functions for querying and interacting with plots
  • Add support for data analysis (e.g. min/max highlighting, averaging, etc)
  • Add support for data exportation (e.g. to CSV, MATLAB .m files, or matplotlib .py files)

At this point, I am looking for contributors and maintainers to assist with the project. If you are interested, please do not hesitate to post issues/PRs to the repository!

@ocornut As I said previously, I feel that this library may only appeal to a small subset of ImGui users. However, I know you have expressed interest in improving the core ImGui plotting interface on a few occasions, and several users have asked for more advanced plots. Therefore, I humbly offer my support to integrate the library, or at least a subset, into ImGui itself at some point in the future. If you agree, I am happy to discuss what changes would need to be made to bring it up to par with the rest of ImGui. As always, thank you for creating such an amazing library!

Nice, thanks for sharing! I'm one of those few using your fancy graphs! More advanced graphs could perhaps be rendered via user callbacks somehow ?

just created the c-api wrapper: https://github.com/sonoro1234/cimplot

@sonoro1234 , that's really awesome! Thank you for taking the time to make the binding. I'll post a link on our README.

@sergeyn, that's a good idea and not something I have given much thought to. When the rest of the library is more mature, I may investigate it. Thanks!

Thank you for taking the time to make the binding.

Not so much time, just reused cimgui utility!! (Once you maked the relevant C friendly changes)

I've added the ability to draw query bounding boxes in plots, which can be then be retrieved with GetPlotQuery() in between BeginPlot()/EndPlot() calls. This can be used to analyze a subset of data, render a zoomed view, and many other possibilities.

Computing the average of selected points:
query

A recreation of @soulthreads imgui_plot demo:
views

Both of these can be found in the ImPlot demo!

Hey, that's some really nice looking plots! Maybe I should actually use your library instead of my own, since you have a lot more features and polish. 😃

Thank you! Your implementation was great inspiration. The only thing I think you will find missing in ImPlot is data tooltips when hovering. However, there is a cursor location tooltip always displayed in the bottom right. Let me know what you think. Would love to get your feedback.

Pie plots have been added:

image

This is awesome! Just wondering if there are there any polar-coordinate plots?

No polar coordinates yet. It's not something I intend to support just yet, but I think at some point it could be added.

Awesome lib, ultra easy to integrate and very well made. I hope this will be merged with ImGUI one day.

Implot is now available on vcpkg : microsoft/vcpkg@4425bf3

Awesome! Would you mind posting an issue on the ImPlot repo to notify others? Thanks!

For anyone interested, I created a Python binding called "mahi-gui". It also wraps ImGui and allows to use custom OpenGL draw calls or have another python module do that (for example Ratcave). It is based on mahi-gui (object oriented) and tries to adhere to the original C++ APIs as closely as possible. It is maintained by hand to make sure everything works as expected and is performant (especially plotting big datasets).

Take a look at the examples to see if it fits you (compared to the other Python bindings which use different approaches)

Closing this issue as ImPlot is grown up and has its stand-alone repository now :) https://github.com/epezent/implot
I'm trying to give visibility to ImPlot changes in every releases notes, seeing it is an amazing extension.

I'd like us to rework the Wiki into a nicer web site where we could show case pictures of widgets.

Sounds good Omar! I really appreciate the visibility and support you've been giving the project.