Advanced 2D Plotting for Dear ImGui

ImPlot

ImPlot is an immediate mode, GPU accelerated plotting library for Dear ImGui. It aims to provide a first-class API that ImGui fans will love. ImPlot is well suited for visualizing program data in real-time or creating interactive plots, and requires minimal code to integrate. Just like ImGui, it does not burden the end user with GUI state management, avoids STL containers and C++ headers, and has no external dependencies except for ImGui itself.

Features

  • GPU accelerated rendering
  • multiple plot types:
    • line plots
    • shaded plots
    • scatter plots
    • vertical/horizontal bars graphs
    • vertical/horizontal error bars
    • stem plots
    • stair plots
    • pie charts
    • heatmap charts
    • images
    • and more likely to come
  • mix/match multiple plot items on a single plot
  • configurable axes ranges and scaling (linear/log)
  • time formatted x-axes (US formatted or ISO 8601)
  • reversible and lockable axes
  • up to three independent y-axes
  • controls for zooming, panning, box selection, and auto-fitting data
  • controls for creating persistent query ranges (see demo)
  • several plot styling options: 10 marker types, adjustable marker sizes, line weights, outline colors, fill colors, etc.
  • 10 built-in and user definable colormaps
  • optional plot titles, axis labels, and grid labels
  • optional and configurable legends with toggle buttons to quickly show/hide plot items
  • default styling based on current ImGui theme, but most elements can be customized independently
  • customizable data getters and data striding (just like ImGui:PlotLine)
  • accepts data as float, double, and 8, 16, 32, and 64-bit signed/unsigned integral types
  • and more! (see Announcements 2020/2021)

Usage

The API is used just like any other ImGui BeginX/EndX pair. First, start a new plot with ImPlot::BeginPlot(). Next, plot as many items as you want with the provided PlotX functions (e.g. PlotLine(), PlotBars(), PlotScatter(), etc). Finally, wrap things up with a call to ImPlot::EndPlot(). That's it!

int   bar_data[11] = ...;
float x_data[1000] = ...;
float y_data[1000] = ...;

ImGui::Begin("My Window");
if (ImPlot::BeginPlot("My Plot")) {
    ImPlot::PlotBars("My Bar Plot", bar_data, 11);
    ImPlot::PlotLine("My Line Plot", x_data, y_data, 1000);
    ...
    ImPlot::EndPlot();
}
ImGui::End();

Usage

Of course, there's much more you can do with ImPlot. Consult implot_demo.cpp for a comprehensive example of ImPlot's features.

Interactive Demo

An online version of the demo is hosted here. You can view the plots and the source code that generated them. Note that this demo may not always be up to date and is not as performant as a desktop implementation, but it should give you a general taste of what's possible with ImPlot. Special thanks to pthom for creating and hosting this!

Integration

  1. Set up an ImGui environment if you don't already have one.
  2. Add implot.h, implot_internal.h, implot.cpp, implot_items.cpp and optionally implot_demo.cpp to your sources. Alternatively, you can get ImPlot using vcpkg.
  3. Create and destroy an ImPlotContext wherever you do so for your ImGuiContext:
ImGui::CreateContext();
ImPlot::CreateContext();
...
ImPlot::DestroyContext();
ImGui::DestroyContext();

You should be good to go!

If you want to test ImPlot quickly, consider trying mahi-gui, which bundles ImGui, ImPlot, and several other packages for you.

Special Notes

  • If you experience data truncation and/or visual glitches, it is HIGHLY recommended that you EITHER:
    1. Handle the ImGuiBackendFlags_RendererHasVtxOffset flag in your renderer when using 16-bit indices (the official OpenGL3 renderer supports this) and use an ImGui version with patch [email protected], OR...
    2. Enable 32-bit indices by uncommenting #define ImDrawIdx unsigned int in your ImGui imconfig.h file.
  • By default, no anti-aliasing is done on line plots for performance gains. If you use 4x MSAA, then you likely won't even notice. However, you can enable software AA per-plot with the ImPlotFlags_AntiAliased flag, or globally with ImPlot::GetStyle().AntiAliasedLines = true;.
  • Like ImGui, it is recommended that you compile and link ImPlot as a static library or directly as a part of your sources. However, if you are compiling ImPlot and ImGui as separate DLLs, make sure you set the current ImGui context with ImPlot::SetImGuiContext(ImGuiContext* ctx). This ensures that global ImGui variables are correctly shared across the DLL boundary.

FAQ

Q: Why?

A: ImGui is an incredibly powerful tool for rapid prototyping and development, but provides only limited mechanisms for data visualization. Two dimensional plots are ubiquitous and useful to almost any application. Being able to visualize your data in real-time will give you insight and better understanding of your application.

Q: Is ImPlot the right plotting library for me?

A: If you're looking to generate publication quality plots and/or export plots to a file, ImPlot is NOT the library for you. ImPlot is geared toward plotting application data at realtime speeds. ImPlot does its best to create pretty plots (indeed, there are quite a few styling options available), but it will always favor function over form.

Q: Where is the documentation?

A: The API is thoroughly commented in implot.h, and the demo in implot_demo.cpp should be more than enough to get you started.

Q: Is ImPlot suitable for plotting large datasets?

A: Yes, within reason. You can plot tens to hundreds of thousands of points without issue, but don't expect millions to be a buttery smooth experience. That said, you can always downsample extremely large datasets by telling ImPlot to stride your data at larger intervals if needed.

Q: What data types can I plot?

A: ImPlot plotting functions accept most scalar types: float, double, int8, uint8, int16, uint16, int32, uint32, int64, uint64. Arrays of custom structs or classes (e.g. Vector2f or similar) are easily passed to ImPlot functions using the built in striding features (see implot.h for documentation).

Q: Can plot styles be modified?

A: Yes. Data colormaps and various styling colors and variables can be pushed/popped or modified permanently on startup. Three default styles are available, as well as an automatic style that attempts to match you ImGui style.

Q: Does ImPlot support logarithmic scaling or time formatting?

A: Yep! Both logscale and timescale are supported.

Q: Does ImPlot support multiple y-axes? x-axes?

A: Yes. Up to three y-axes can be enabled. Multiple x-axes are not supported.

Q: Does ImPlot support [insert plot type]?

A: Maybe. Check the demo, gallery, or Announcements (2020/2021)to see if your desired plot type is shown. If not, consider submitting an issue or better yet, a PR!

Q: Does ImPlot support 3D plots?

A: No, and likely never will since ImGui only deals in 2D rendering.

Q: My plot lines look like crap!

A: See the note about anti-aliasing under Special Notes above.

Q: Does ImPlot provide analytic tools?

A: Not exactly, but it does give you the ability to query plot sub-ranges, with which you can process your data however you like.

Q: Can plots be exported/saved to image?

A: Not currently. Use your OS's screen capturing mechanisms if you need to capture a plot. ImPlot is not suitable for rendering publication quality plots; it is only intended to be used as a visualization tool. Post-process your data with MATLAB or matplotlib for these purposes.

Q: Can ImPlot be used with other languages/bindings?

A: Yes, you can use the generated C binding, cimplot with most high level languages. DearPyGui provides a Python wrapper, among other things. A Rust binding, implot-rs, is currently in the works. An example using Emscripten can be found here.

Owner
Evan Pezent
PhD candidate studying robotics in the Mechatronics and Haptic Interfaces Lab at Rice University.
Evan Pezent
Comments
  • Visualisation Improvement ideas/fixes

    Visualisation Improvement ideas/fixes

    1.) Minor ticks should not suddenly become major ticks, but gradually blend into major ticks. New minor ticks should blend in out of completely transparent ones. This will look much nicer when you do zooming, especially very rapid zooming. The point is not to have sudden changes in an image 2.) Add very mild animation on zooming - instead of sudden changes in zoom, zoom in gradually, starting at very fast speed, and slowing down when reaching zoom target, play the whole animation within 0.5-0.8second so it is still as sharp and responsive and not annoying. Also put it on a flag 3.) When zooming in, amount of digits for each tick grows and at some point they start to overlap. image I suggest skipping outputting text for ticks which will overlap with previous tick, with preference for major ticks of course.

  • Add GPU-accelerated heatmaps

    Add GPU-accelerated heatmaps

    As promised in #219, I managed to implement GPU-accelerated heatmaps! I haven't done any serious benchmarks but the performance gains I've seen in some applications are quite significant.

    This PR is pretty much ready to be merged, but there are some small issues that should be addressed:

    1. OpenGL doesn't support double nor *int64_t (aka ImU64/ImS64). If this kind of data is passed to a heatmap, it is internally converted to float or ImU32/ImS32 (respectively).
    2. When using OpenGL acceleration, the interpolation tables for heatmaps are unnecessary. Maybe we could only enable them in case this optimization is disabled
    3. Right now I use the same trick ImGui's main.cpp file uses to access OpenGL functions, which is rely on a macro definition to include one of the many supported libraries. It is possible to implement our own OpenGL loader so that we don't rely on any external library (ImGui will still depend on that library though), but that would add a bit of complexity maybe.
    4. Log-Log, Lin-Log and Log-Lin axis are not yet implemented.

    I tried to implement this as straightforward as possible, and with as little modifications to the 'core' of the library as possible. Also, all the implementation details are inside the file backends/implot_opengl.cpp. If the macro IMPLOT_ENABLE_OPENGL3_ACCELERATION is defined, then that file will compile and the library will use the shader-accelerated code. If not, it will default to the current method.

    I will update this PR once I have some benchmarks to show you, but the performance gains should be significant :)

    Any comments, optimizations, questions or changes are always welcome :D

  • Multi-Axis Support

    Multi-Axis Support

    Moving discussions of multi-axis support to a separate issue. Previous comments below:

    https://github.com/epezent/implot/issues/1#issuecomment-626177655

  • Support for other dataset types

    Support for other dataset types

    I wish I could use ImPlot for audio data, which e.g. Spotify delivers as Int16 (signed) interleaved samples, which feed to the audio device as same. My FFTs yield integer ranges as well. I'd rather avoid converting entire blocks of ints to floats for trivial display, simply to skirt a library inflexibility.

    ImPlot's core piece - the data it operates on and that data's type - being limited to floating point is a fundamental inconvenience. @ocornut's suggestion to templatize the datatype internally, then expose type-specific APIs, seemed to be summarily dismissed. https://github.com/epezent/implot/issues/36#issuecomment-630772991

    @epezent you mentioned there that templates "make the header a mess" but the dual "float then double" repeated function prototypes don't seem elegant either. Does anyone else have need for different dataset types? Surely someone has. I'm considering a fork to investigate a templated approach but would rather not repeat someone else's failed attempt at wheel reinvention. :-)

    By the way, @epezent, nice work on this! It looks great.

  • Announcements and New Features (2020)

    Announcements and New Features (2020)

    Announcements of changes and new features will be posted here. Click Subscribe to the right to receive updates!

    PLEASE DO NOT COMMENT ... EMOJIS ARE WELCOME :)

  • AlignedPlots: Y/X axis padding over multiple plots

    AlignedPlots: Y/X axis padding over multiple plots

    To have same Y axis padding, ImPlot::BeginSubPlots() must be called before 1st ImPlot::BeginPlot() and ImPlot::EndSubPlots() must be called after last ImPlot::EndPlot(). Peek 2020-11-10 22-44

    https://github.com/epezent/implot/issues/53#issuecomment-723526658

  • Candlestick chart

    Candlestick chart

    Hi. Thank you very much for such an amazing library! Would you mind to implement a candlestick chart? It would be great to have a function with signature like

    void PlotCandlestickChart(const char* label_id, const float* xs, const float* opens, const float* closes, const float* lows, const float* highs, int count, int offset, int stride)
    

    I have a very basic implementation which looks like this candles The implementation is very straightforward and based on the error bars code, but I can share it here if you want.

    Let me explain some problems I've faced here:

    1. As you can see, I use 2 colors for candles. The main problem is you cannot show a 2-colored marker in the legend box. I see 2 solutions here: either to support a multicolor markers in the legend, or use one color, but mark rising and falling candles with solid and hollow filling. I'm not sure what option is more suitable for implot.
    2. It would be great to be able to show a time on the X axis in some form.
    3. I'm not sure if this is a topic for implot, but it would be great to have some tools to show the candle parameters (OHLC values) when mouse is hovered or clicked the candle.

    Please let me know if I can help somehow. Thanks!

  • [Proposition] Online interactive demonstration

    [Proposition] Online interactive demonstration

    Your library is truly awesome, congrats!

    When it come to C++ libraries, most of the time there is most of the time no easy way to get a working demonstration. First, you have to download the code setup the build environment, etc. There, C++ is lagging behind some other languages, especially on the web.

    However, emscripten can help a lot in this case. In order to tryr to fill this gap, I spent a few hours this afternoon in order to make an online demo of your library.

    It is live here, and the source code for this demo is on github.

    Here are some screenshots:

    implot demo: image

    source code browser with access to the different demos: image

    It runs at 120 fps, except for the benchmark (which I suspect is blocked because it may consume too much memory)

    If you are interested, you could may be use this in order to add an interactive demo in your Readme. Feel free to deploy the wasm files on any server of your choice.

    Thanks

  • Line rasteriation issues for dense plots

    Line rasteriation issues for dense plots

    When you have super dense plots (many points hit a pixel), you can see holes in the rasterization pattern. Consider following plot, which plots a line: ImPlot::PlotLine("line, [](void*, int idx) { float v = float( 3.0 * idx / (1000000 - 1)); return ImVec2(v, v); }, nullptr, 1000000); You can observe single pixels missing on a plot. I believe it's because triangles generated for line segments do not have exactly same coordinates. (PS. you need my million line PR for this to work)

  • Box selection [Mac]

    Box selection [Mac]

    Hello! I'm a bit confused with the box selection process. Firstly, there is a line that ImPlotFlags_Selection flag was changed to ImPlotFlags_BoxSelect (see implot.cpp), but I can't find neither statement that ImPlotFlags_BoxSelect has been deleted, nor that it's being used in the code. So the main question is how to enable box selection/zooming?

  • Performance impact of offset and stride / wrap around

    Performance impact of offset and stride / wrap around

    The problem

    Just indexing the data (patched out ImPosMod() with just idx) gives a 30% fps boost in the benchmark (mahi-gui) compared to the current implementation honouring offset, stride. Before ImPosMod() was patched into it, the custom getter function version was faster. To my testing the penalty of using a getter function versus raw array pointers (all without ImPosMod and OffsetAndStride()) is surprisingly low (I suspect because there is already a lot of function calls for drawing each data point anyways).

    ~~The~~ A Solution

    One way to improve this is to add overloads without offset and stride parameters (and special getters in implot_items.cpp) for all functions. This will lead to double the amount of template instantiations though. A leaner variant would be to add overloads just for the _G functions. This also gives about 30% more fps in the plots benchmark.

    If you have a better idea how to solve this I'm happy to rebase the PR.

  • Add polar charts (enhancement)

    Add polar charts (enhancement)

    Please add to the library a "scatter" plot on polar axis. It will be good to have to choose a "scatter" view:

    1. Arc figures. Inspired by nttiny library and looks like this image

    2. Circle scatters. It looks like matplotlib scatter plot image

  • Added new bindings for .NET

    Added new bindings for .NET

    That's my contribution to your project, bindings for .NET which, among other things, includes implot documentation directly from within IntelliSense.

    Thank you, have a good year!

  • "Too many vertices in ImDrawList using 16-bit indices (LTTB solution?)

    I'm trying to plot data with hundreds of thousands of data points.

    It would be ideal to have implot incorporate an LTTB solution to automatically downsample data as the user zooms out / in of the data

  • PlotLine() is broken

    PlotLine() is broken

    The diff 63d5ed94b77acdf73201a00074bfd80467f50f0a introduced some breaking changes in how ImPlot::PlotLine() works.

    Before:

    Before

    After:

    After

    Code:

    auto Sparkline = [](const char* id, const float* values, int count, float min_v, float max_v, int offset, const ImVec4& col,
                        const ImVec2& size) {
    	ImPlot::PushStyleVar(ImPlotStyleVar_PlotPadding, ImVec2(0, 0));
    	ImPlot::SetNextAxesLimits(0, count - 1, min_v, max_v, ImGuiCond_Always);
    	if (ImPlot::BeginPlot(id, size, ImPlotFlags_CanvasOnly | ImPlotFlags_NoChild)) {
    		ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_NoDecorations, ImPlotAxisFlags_NoDecorations);
    		ImPlot::PushStyleColor(ImPlotCol_Line, col);
    		ImPlot::PlotLine(id, values, count, 1, 0, offset);
    		ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f);
    		ImPlot::PlotShaded(id, values, count, 0, 1, 0, offset);
    		ImPlot::PopStyleVar();
    		ImPlot::PopStyleColor();
    		ImPlot::EndPlot();
    	}
    	ImPlot::PopStyleVar();
    };
    
  • Persist legend location and flags

    Persist legend location and flags

    Hi!

    Thanks for this great library. I have a question: How do I persist the location and inside/outside flag of the legend so that if the app is closed and opened again the legend is still at the same position. Is there a method to query the state of the legend? Or something like SetupLegend(ImPlotLocation *location, ImPlotLegendFlags *flags) with references which modifies the current location and flags when the user configures the legend. Then location and flags could be saved on exit and loaded on start of the app.

  • ImPlotPoint::operator[] bounds checking

    ImPlotPoint::operator[] bounds checking

    In implot.h, you have:

    // Double precision version of ImVec2 used by ImPlot. Extensible by end users.
    struct ImPlotPoint {
        double x, y;
        ....
        double  operator[] (size_t idx) const { return (&x)[idx]; }
        double& operator[] (size_t idx)       { return (&x)[idx]; }
        ....
    };
    

    These functions do not do bounds checking and may thus read outside the struct's values. ImGui's ImVec2 does the following:

    struct ImVec2
    {
        float                                   x, y;
        ....
        float  operator[] (size_t idx) const    { IM_ASSERT(idx <= 1); return (&x)[idx]; }    // We very rarely use this [] operator, the assert overhead is fine.
        float& operator[] (size_t idx)          { IM_ASSERT(idx <= 1); return (&x)[idx]; }    // We very rarely use this [] operator, the assert overhead is fine.
        ....
    };
    

    And additionally has a pair of macros IM_MSVC_RUNTIME_CHECKS_OFF and IM_MSVC_RUNTIME_CHECKS_RESTORE that it wraps the struct with. Since implot.h imports imgui.h, you could directly use IM_ASSERT as well as the above other macros. Could you consider doing so?

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

Dear ImGui (This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addit

Jan 7, 2023
Real-time GUI layout creator/editor for Dear ImGui
Real-time GUI layout creator/editor for Dear ImGui

ImStudio Real-time GUI layout creator/editor for Dear ImGui Inspired by Code-Building/ImGuiBuilder Features Drag edit Property edit Covers most of the

Jan 9, 2023
Dear ImGui prototyping wrapper.

LabImGui Prototyping framework LabImGui wraps up creating a window, GL bindings, and a full screen docking set up with ImGui so that all of the boiler

Dec 5, 2022
An integrated information center created with dear ImGui using modern C++ design / coding style.

ImGui info-center Introduction An integrated notification and information center created with dear ImGui. Interfaces and variables are designed under

Oct 29, 2022
Addon widgets for GUI library Dear ImGui.
Addon widgets for GUI library Dear ImGui.

ImGui-Addons Addon widgets for GUI library Dear ImGui. File Dialog A simple cross-platform file dialog that uses dirent interface for reading director

Jan 7, 2023
This is a software renderer for Dear ImGui. I built it not out of a specific need, but because it was fun
This is a software renderer for Dear ImGui. I built it not out of a specific need, but because it was fun

Dear ImGui software renderer This is a software renderer for Dear ImGui. I built it not out of a specific need, but because it was fun. The goal was t

Dec 22, 2022
Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui
Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui

ImGuizmo Latest stable tagged version is 1.83. Current master version is 1.84 WIP. What started with the gizmo is now a collection of dear imgui widge

Dec 27, 2022
This is a thin c-api wrapper programmatically generated for the excellent C++ immediate mode gui Dear ImGui.

cimgui This is a thin c-api wrapper programmatically generated for the excellent C++ immediate mode gui Dear ImGui. All imgui.h functions are programm

Jul 5, 2021
Nice things to use along dear imgui
Nice things to use along dear imgui

Mini hexadecimal editor! Right-click for option menu. Features: Keyboard controls. Read-only mode. Optional Ascii display. Optional HexII display. Goto address. Highlight range/function. Read/Write handlers.

Jan 1, 2023
Window and GUI system based on Dear ImGui from OCornut
Window and GUI system based on Dear ImGui from OCornut

ImWindow Window and GUI system based on ImGui from OCornut. Include docking/floating window, multi window and multi render support. Platform Actually

Dec 20, 2022
A permissively licensed markdown single-header library for Dear ImGui.
A permissively licensed markdown single-header library for Dear ImGui.

Support development of imgui_markdown through GitHub Sponsors or Patreon imgui_markdown Markdown For Dear ImGui A permissively licensed markdown singl

Jan 8, 2023
Sample Unreal Engine 5.0.1 C++ Project That Incorporates Dear ImGui

UE5 With Dear ImGui A sample Unreal Engine 5.0.1 C++ project that incorporates the Dear ImGui graphical user interface library. YouTube Tutorial This

Dec 25, 2022
Simple ImGui external base. Uses ImGui DX9.
Simple ImGui external base. Uses ImGui DX9.

ImGui External Base ??️ What is this? ⚡ Hello all! I used to use noteffex's loader base for all my external ImGui projects. I got bored of using this

Jun 29, 2022
An addon of imgui for supporting docks in the imgui's window
An addon of imgui for supporting docks in the imgui's window

An addon of imgui for support dock in the window

Nov 29, 2022
wxWidgets is a free and open source cross-platform C++ framework for writing advanced GUI applications using native controls.
wxWidgets is a free and open source cross-platform C++ framework for writing advanced GUI applications using native controls.

About wxWidgets is a free and open source cross-platform C++ framework for writing advanced GUI applications using native controls. wxWidgets allows y

Jan 7, 2023
CMakeLists wrapper around imgui

ImGui Wrappings This is a trifold wrapper for the Dear ImGui library. Ease integration with CMake, Provide an RAII mechanism for ImGui scopes, Provide

Dec 8, 2022
super duper simple gui for C, wrapping imgui and stb

super duper simle gui for C, wrapping imgui and stb You can use it as a static library with cmake. See the example directory for a complete example. E

May 19, 2022
KeyAuth login form made with ImGui.

KeyAuth-ImGui-Example KeyAuth ImGui Example Download Repository Download the DirectX SDK

Dec 16, 2022
ImGuiBase - A very good & simple external ImGui base

ImGuiBase Join CProject to learn about ImGui! https://discord.gg/dnkdDuUtQu Check out our website: https://cproject.xyz Check out the youtube tutorial

Dec 23, 2022