# Makie - improving performance with animations?

**URL:** <https://discourse.julialang.org/t/makie-improving-performance-with-animations/87478>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [September 19, 2022, 3:41pm UTC](https://discourse.julialang.org/t/makie-improving-performance-with-animations/87478 "2022-09-19T15:41:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![rkube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkube/32/211198_2.png) [@rkube](https://discourse.julialang.org/u/rkube)\
**Post date:** [September 19, 2022, 3:41pm UTC](https://discourse.julialang.org/t/makie-improving-performance-with-animations/87478/1 "2022-09-19T15:41:38Z")

</div>

Hi,  
I’m looking into animating results from a kinetic simulation using makie and got some basic animations going. Now I’m trying to improve about performance.  
This script [kinetic\_anim.jl · GitHub](https://gist.github.com/rkube/45d799970fd2e7a0b93cc2991e48facf) animates the trajectories, of length 20,000, for 1,000 particles in the simulation mesh.

The final record loop runs at about 25 iterations per second on my laptop Corei5-8350U CPU @ 1.70GHz, and cpu utilization is at 60-70%, using only a single core. Does someone maybe have an idea how to increase performance here?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [September 19, 2022, 3:54pm UTC](https://discourse.julialang.org/t/makie-improving-performance-with-animations/87478/2 "2022-09-19T15:54:11Z")

</div>

You could try to profile the recording to see where most time is spent.

---

<div class="post-metadata">

**Author:** ![rkube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkube/32/211198_2.png) [@rkube](https://discourse.julialang.org/u/rkube)\
**Post date:** [September 19, 2022, 5:51pm UTC](https://discourse.julialang.org/t/makie-improving-performance-with-animations/87478/3 "2022-09-19T17:51:59Z")

</div>

Good idea, here is the trace: [profile.txt · GitHub](https://gist.github.com/rkube/3c9ca2fade6c377e785d8ef770597cbd)

Line 1363 of the trace tells me that a large fraction of backtraces are taken in `11613 @Observables/src/Observables.jl:86; setindex!(observable::Observable, val::Any)`  
Probably when the animation loop mutates all observables:

```julia
    for (idx, traj) in enumerate(traj_list)
       traj[] = push!(traj[], anim_step(t, idx))
    end

```

Right now I define each particle as an independent observable, which leads me to 1,000 observables.  
Is there maybe a smarter way of plotting the particle trajectories?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [September 19, 2022, 9:04pm UTC](https://discourse.julialang.org/t/makie-improving-performance-with-animations/87478/4 "2022-09-19T21:04:26Z")

</div>

Oh yeah 1000 observables are rarely a good sign… You could try the `series` plot type, it is just a layer on top of `lines` but makes it easier to plot multiple lines in one call. It condenses the data down to just one array, which is most efficient in terms of interfacing with the GPU. You can also build such a vector yourself, though, it’s just a NaN separated list of points.

I’d assume you could get pretty good performance by:

- make one `arr = Vector{Point3f}` of length 20,000 \* 1,000 + 999 NaN points in between
- make one `obs = Observable(points)`
- plot that via `lines!(ax_anim, obs)`
- when updating, mutate the original `arr` and update the points
- then just `notify(obs)` to update the lines

---

<div class="post-metadata">

**Author:** ![rkube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkube/32/211198_2.png) [@rkube](https://discourse.julialang.org/u/rkube)\
**Post date:** [September 27, 2022, 7:21pm UTC](https://discourse.julialang.org/t/makie-improving-performance-with-animations/87478/5 "2022-09-27T19:21:19Z")

</div>

Thanks, that gives me a much more performant skeleton to build my animation on.  
Here is some basic code:

```julia
num_anim_step = 100
num_anim_ptl = 10
# Fill this array consecutively with particle values at different time-steps
# At the last time-step, a NaN separates the values of different particles
# For example when num_anim_step = 10:
# ptl1: 1...10
# ptl2: 12...21
# ptl3: 23...32
# etc.
arr = [CairoMakie.Point2f(NaN, NaN) for i in 1:(num_anim_ptl * (num_anim_step + 1))]
obs = Observable(arr)

f_anim, a_anim, p_anim = lines(arr)

record(f_anim, "test.mp4", 1:num_anim_step; framerate=1) do t
    for ptl in 1:num_anim_ptl
        # Replace the NaN in the array with particle trajectory up to current time step
        arr[(ptl - 1) * num_anim_step + t] = CairoMakie.Point2f(t, ptl + 0.1 * t)
    end
    notify(obs)
end

```
