Plots and display

I am doing a cheap animation by displaying a plot every 1/60th of a second using the Plots package. Unfortunately, it is not very fast. It happens that this is the call to the display function that is slow.

This can be seen already at the repl.

  julia> @time Plots.plot(rand(2), rand(2))
    0.000373 seconds (402 allocations: 42.781 KiB)

  julia> @time display(Plots.plot(rand(2), rand(2)))
    0.002729 seconds (4.85 k allocations: 383.812 KiB)

Is there a faster way to update the plot in the window from a script?

Are you open to using a different plotting package? GLMakie has some good options here, where you can update an Observable and the plot just updates without redrawing.

GLMakie.jl is fast, other alternatives: GR.jl, Gnuplot.jl and Gaston.jl

Maybe you can test also the GR backend in Plots.jl, but using GR.jl directly is faster then through Plots

Yes, I can try to use GR directly. What would be the GR equivalent to the Plots call

    Plots.plot([0,1], [1,0], xlims=(-1.2,1.2), ylims=(-1.2,1.2), title = "",
               legend = false, grid = false, showaxis = false, 
               linecolor = :black, size = (600,600))

?
I have browsed GR.jl documentation (and source) but I was unable to find the list of parameters available to the plot command. At the moment, I just need to draw a line between two points (no grid, no box, no axis, just a line).

I tried with GR.jl, but it is not faster than Plots with the GR backend. I guess I will try Makie.

0.002729 seconds

from your @time output. That is > 358 Hz. Isn’t that enough for your use case (plot at 60 Hz)?

I am plotting more than two points!

If you’d like to try Makie, the equivalent would be

using GLMakie

lines([0, 1], [1, 0], color=:black,
      axis=(limits=(-1.2, 1.2, -1.2, 1.2),
            xgridvisible=false, ygridvisible=false),
      figure=(resolution=(600, 600),))

For the animation you can do something like this:

using GLMakie

# You can prepare the figure and axis config like this,
# and pass them to `update_theme!` or to a plot function as done below
figure = (resolution=(600, 600),)
axis = (limits=(-1.2, 1.2, -1.2, 1.2),
        xgridvisible=false, ygridvisible=false)

points = Observable([Point2f(0,1), Point2f(1,0)])
lines(points, color=:black; figure, axis)

# The previous line opens a window and shows the initial plot
# You can then update it using `point[]` to change the array of points

for i = 1:100
    points[] = push!(points[], rand(Point2f))
    sleep(1/60)
end
1 Like