# \[ANN\] ImPlot.jl -- FAST real-time plotting for CImGui.jl

**URL:** <https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087>\
**Category:** Package Announcements\
**Created:** [July 14, 2020, 11:23pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087 "2020-07-14T23:23:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![wsphillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsphillips/32/6777_2.png) [@wsphillips](https://discourse.julialang.org/u/wsphillips)\
**Post date:** [July 14, 2020, 11:23pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/1 "2020-07-14T23:23:49Z")

</div>

I wrapped a really nice plotting extension called [implot](https://github.com/epezent/implot), a C++ plugin for [Dear ImGui](https://github.com/ocornut/imgui). With some clutch help from @Gnimuc and the magic of BinaryBuilder.jl this package can be imported into a Julia session that’s using `CImGui.jl` and everything should “JustWork”.

The plotting is straight forward and, notably, quite fast even with 100s of thousands of points. There’s also optional arguments to do strided/offset array access for interleaved data. Generally a nice solution for anyone that wants to do real-time visualization of analog or digital sensor data (in my case, electrophysiology signals).

~~If there’s interest from the community, I might go to the effort of documenting it a little more thoroughly and throwing it up on the registry.~~ **Update** : ImPlot.jl is now on the registry–you can just `]add ImPlot` now. The underlying C++ lib has also been updated to include a couple extra features (namely shaded line plots).

> **[GitHub - wsphillips/ImPlot.jl: Plotting extension library for CImGui.jl](https://github.com/wsphillips/ImPlot.jl)**
>
> Plotting extension library for CImGui.jl. Contribute to wsphillips/ImPlot.jl development by creating an account on GitHub.

 ![plots](https://global.discourse-cdn.com/julialang/original/3X/9/7/97b93143d8ccbbbe4c2ea686ad06df996d1849d3.gif)

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [July 15, 2020, 2:06am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/2 "2020-07-15T02:06:16Z")

</div>

This is great. Also, not so great as I am now thoroughly confused about what plotting library to switch over to from `ggplot`. There is `Plots.jl` which is the most native and FTOP is reduced significantly in 1.5, there is `VegaLite.jl` which somewhat follows the Grammar of Graphics of `ggplot`, there is `gnuplot.jl` which is my top contender to switch to, `Makie.jl` which seems more tedious than necessary, but packs some serious power, and a few others I can’t recall.

But this is great. Will definitely try it out in the next few days 😀

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [July 15, 2020, 5:57am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/3 "2020-07-15T05:57:39Z")

</div>

Implot, along with ImGui, is mainly for writing GUI tools. You could play with it online. 😉

[https://traineq.org/imgui\_manual/src/imgui\_manual.html](https://traineq.org/imgui_manual/src/imgui_manual.html)

[https://traineq.org/implot\_demo/src/implot\_demo.html](https://traineq.org/implot_demo/src/implot_demo.html)

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [July 15, 2020, 8:44am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/4 "2020-07-15T08:44:47Z")

</div>

Would it make sense to integrate ImPlot.jl into CImGui.jl ?

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [July 15, 2020, 10:05am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/5 "2020-07-15T10:05:37Z")

</div>

This is great. I needed a real-time vizualisation lib, so today I decided “Let me ask on the Julia discourse about the situation of real-time vizualisation libs. No, first let me search to see what has currently been announced.”

So I found this thread. Started 11 hours ago! How lucky 🙂

Now excuse my breathtaking ignorance, but… From what I understand this is a wrapper to some C or C++ libs (great!). But the demo (which @gnimuc posted) is on the browser. How does that work?

---

<div class="post-metadata">

**Author:** ![wsphillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsphillips/32/6777_2.png) [@wsphillips](https://discourse.julialang.org/u/wsphillips)\
**Post date:** [July 15, 2020, 10:15am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/6 "2020-07-15T10:15:52Z")

</div>

Those demos are done independently by some other people, who got it running in the browser with emscripten + WebGL afaik. The Julia libraries here are calling natively compiled binaries and use an OpenGL backend. The performance is slower in the browser, but it’s also easy to give someone a link to see what’s going on.

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [July 15, 2020, 10:22am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/7 "2020-07-15T10:22:07Z")

</div>

That’s exactly what I wanted to hear, thank you 😄

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [July 15, 2020, 10:30am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/8 "2020-07-15T10:30:16Z")

</div>

Thankyou. I bought a pulse oximeter sensor and a three lead heart sensor for my Pi or Jetson Nano. This will be ideal to display traces from these.

Di dI say traces? Yes indeed - I am old enough to have used pen plotters.

---

<div class="post-metadata">

**Author:** ![wsphillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsphillips/32/6777_2.png) [@wsphillips](https://discourse.julialang.org/u/wsphillips)\
**Post date:** [July 15, 2020, 10:33am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/9 "2020-07-15T10:33:28Z")

</div>

My lab has rolls of old chart paper in the back of a cabinet somewhere. Still call them traces from time to time 🙂

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [August 15, 2020, 6:42pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/10 "2020-08-15T18:42:03Z")

</div>

I find this package really useful combined with CImGui. Any chance of registering it? Thank you for the great work!

---

<div class="post-metadata">

**Author:** ![wsphillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsphillips/32/6777_2.png) [@wsphillips](https://discourse.julialang.org/u/wsphillips)\
**Post date:** [August 15, 2020, 6:54pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/11 "2020-08-15T18:54:22Z")

</div>

Sure. I was waiting for another tag from implot since there’s some added plot styles and options. That has now been done and the maintainer of cimplot has regenerated bindings to match. The implot C++ API was changing a lot, so that’s why I hesitated registering it–there were breaking changes happening. However, it looks like the dust has settled now. I have to rebuild the JLL, add in the extra API functions and it should be more or less ready for registration. I’ll post an update when I get around to it.

---

<div class="post-metadata">

**Author:** ![wsphillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsphillips/32/6777_2.png) [@wsphillips](https://discourse.julialang.org/u/wsphillips)\
**Post date:** [August 24, 2020, 9:36am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/12 "2020-08-24T09:36:53Z")

</div>

ImPlot.jl is now on the public registry 🙂

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [August 24, 2020, 11:34am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/13 "2020-08-24T11:34:51Z")

</div>

Awesome! Thank you so much! I’m using it to develop an oscilloscope front panel at the moment:)

---

<div class="post-metadata">

**Author:** ![sairus7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sairus7/32/10816_2.png) [@sairus7](https://discourse.julialang.org/u/sairus7)\
**Post date:** [November 5, 2020, 4:06pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/14 "2020-11-05T16:06:34Z")

</div>

> [@Gnimuc](#):
>
> [implot\_demo](https://traineq.org/implot_demo/src/implot_demo.html)

It would be nice to have the same demo with ImPlot.jl!

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [February 7, 2021, 2:22pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/15 "2021-02-07T14:22:57Z")

</div>

What exactly is the difference between ImPlot.jl and CImGui.jl? Looking at the demo.jl files of both, it seems they both CImGui’s interface.

I have an application that produces real-time metrics and I would like to use ImPlot.jl/CImGui.jl to plot them. Question: what is the lowest effort way of putting my real-time metrics into a real-time plot? I was looking at ImPlot’s [demo.jl](https://github.com/wsphillips/ImPlot.jl/blob/0ad0d6ad7893977a9248f6a720629c41cad1d91a/demo/demo.jl#L66) trying to figure out how the interface works, but it looks like all the interesting plots in that example are actually implemented in [some C++ code](https://github.com/epezent/implot/blob/b95b23fec80dfe547da8905b570a9db30becf904/implot_demo.cpp#L122). How do I plot real-time from Julia?

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [February 7, 2021, 3:05pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/16 "2021-02-07T15:05:12Z")

</div>

Copy pasting from a sample somewhere I could get a basic real-time plot working in Julia:

```julia
rt_buffer = CircularBuffer{Float64}(1000)

( ... )

if show_main_window
    @c CImGui.Begin("Plot Window", &show_main_window)
    push!(rt_buffer, rand())
    y = collect(rt_buffer)
    ImPlot.SetNextPlotLimits(0.0,1000,0.0,1.0, ImGuiCond_Once)
    if (ImPlot.BeginPlot("Foo", "x1", "y1", CImGui.ImVec2(-1,300)))
        ImPlot.PlotLine(y)
        ImPlot.EndPlot()
    end
    CImGui.End()
end

```

However, I’d rather not have to copy my `CircularBuffer` to a `Vector` every time I want to plot it. Is it possible to avoid copying? Doing `ImPlot.PlotLine(rt_buffer)` throws:

```julia
┌ Error: Error in renderloop!
│ exception = conversion to pointer not defined for CircularBuffer{Float64}
└ @ Main ~/demo.jl:147

```

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [February 7, 2021, 3:57pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/17 "2021-02-07T15:57:45Z")

</div>

Alright, I just discovered that all the functions that [demo.jl](https://github.com/Gnimuc/CImGui.jl/blob/cf9d4adc5f5c4134ec72cbf3ed366d16e61adaaf/demo/demo.jl) uses are implemented in files in [examples/](https://github.com/Gnimuc/CImGui.jl/tree/cf9d4adc5f5c4134ec72cbf3ed366d16e61adaaf/examples).

Excuse the drivel.

Ok, another question. What is the recommended way of integrating an app with the display?

My app has a loop, and so does the display (e.g. [this](https://github.com/Gnimuc/CImGui.jl/blob/cf9d4adc5f5c4134ec72cbf3ed366d16e61adaaf/demo/demo.jl#L68)).

So should I put the display update inside the app’s loop and implicitly let the app’s loop control the display rate? Or should I have the app running in one thread, in display on another thread, and pass data from the former to the latter by using some shared data structure? Or how?

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 8, 2021, 9:53am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/18 "2021-02-08T09:53:58Z")

</div>

> [@freeman](#):
>
> What is the recommended way of integrating an app with the display?

The simplest way is to use coroutine(`yield()` in your app loop like [this](https://github.com/Gnimuc/CImGui.jl/blob/cf9d4adc5f5c4134ec72cbf3ed366d16e61adaaf/examples/Renderer.jl#L74))

> [@freeman](#):
>
> Or should I have the app running in one thread, in display on another thread, and pass data from the former to the latter by using some shared data structure? Or how?

If you’d like to support macOS, please make sure GLFW runs on the main thread, that’s a limitation of macOS.

---

<div class="post-metadata">

**Author:** ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)\
**Post date:** [February 12, 2021, 11:31pm UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/19 "2021-02-12T23:31:48Z")

</div>

Thanks for the response. I still haven’t figured it out though, I guess because I don’t understand `yield()`.

My application loop is schematically:

```julia
initialize!(state)
while true
    update!(state)
end

```

Now, by copy pasting code around I’ve made it work by not using my app loop and using your renderer loop instead. I.e. this works:

```julia
initialize!(state)

try
    while !GLFW.WindowShouldClose(window)
        GLFW.PollEvents()
        ImGui_ImplOpenGL3_NewFrame()
        ImGui_ImplGlfw_NewFrame()
        CImGui.NewFrame()

        # below is my code (schematically)
        # inspired by copy pasting from your examples
        update!(state)
        y = collect(state)
        ImPlot.SetNextPlotLimits(0.0,1000,0.0,1.0, ImGuiCond_Once)
        if (ImPlot.BeginPlot("Foo", "x1", "y1", CImGui.ImVec2(-1,300)))
            ImPlot.PlotLine(y)
            ImPlot.EndPlot()
        end
        CImGui.End()
        # end of my code

        CImGui.Render()
        GLFW.MakeContextCurrent(window)
        display_w, display_h = GLFW.GetFramebufferSize(window)
        glViewport(0, 0, display_w, display_h)
        glClearColor(0.2, 0.2, 0.2, 1)
        glClear(GL_COLOR_BUFFER_BIT)
        ImGui_ImplOpenGL3_RenderDrawData(CImGui.GetDrawData())

        GLFW.MakeContextCurrent(window)
        GLFW.SwapBuffers(window)
    end
catch e
    @error "Error in renderloop!" exception=e
    Base.show_backtrace(stderr, catch_backtrace())
finally
    ImGui_ImplOpenGL3_Shutdown()
    ImGui_ImplGlfw_Shutdown()
    CImGui.DestroyContext(ctx)
    GLFW.DestroyWindow(window)
end

```

Obviously I would like to decouple my `update!` for your renderer. Exactly how should this be re-organized? From the example that you linked to (the one with the `renderloop` with a `yield()`) I’m guessing that somehow I’m supposed to wrap my code into a `ui()` function and pass it to the `renderloop`, but I can’t see exactly how. Additionally, where would I put the `initialize!(state)` line? If I just put it inside `ui()` then it would be run on every loop.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [February 13, 2021, 8:55am UTC](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087/20 "2021-02-13T08:55:34Z")

</div>

@freeman I just wrote a [short step-by-step post](https://github.com/Gnimuc/CImGui.jl/discussions/39) to demonstrate how to do state-management with CImGui.jl. Hopefully this will answer your questions. Feel free to ask questions at Github Discussions.

> **[How to do simple state-management with pure CImGui · Gnimuc/CImGui.jl ·...](https://github.com/Gnimuc/CImGui.jl/discussions/39)**
>
> Loading packages Before reading this short tutorial, it's highly recommended to take a glance at Renderer.jl to at least get an idea about the fact that the render() function is running asynchronou...

[Next page](https://discourse.julialang.org/t/ann-implot-jl-fast-real-time-plotting-for-cimgui-jl/43087.md?page=2)
