On-the-fly Animation in IJulia Notebooks


#1

I recently revisited how to do on-the-fly visualisation in an IJulia notebook, i.e., plotting results while the computation is still running. This was discussed a while back in Google groups link

I’ve tried the same scheme with Plots.jl with Plotly backend, and I am thrilled that this still works. (Julia 0.5.1pre). Below is the code for anybody interested.

But my key issue back then and still now is: why does it need to be so complicated? I.e. why can I not simply write

x = linspace(0, 2*pi, 100) |> collect 
dt, nsteps = 0.03, 300
for n = 1:nsteps
    plot(x, sin(x - dt*n))
end

Is there a fundamental barrier? I would really appreciate this functionality not just for my own research but also for teaching with Julia. (I can’t promise but I might even be able to find some funding to get it implemented.)


Here is the promised code now:

CELL 1

using Reactive, Interact, Plots
Plots.plotlyjs()

function myplot(data)    
    Plots.plot(data[1], data[2], xlims=(0, 2*pi), ylims=(-1.2,1.2))
end

x = linspace(0, 2*pi, 100) |> collect 
myinput = Signal((x, sin(x)))
lift(myplot, my input)

CELL 2

dt, nsteps = 0.03, 300
for n = 1:nsteps
    push!(myinput, (x, sin(x - n*dt)))
end

Plotting from within a loop using GR?
#2

I don’t understand… What “doesn’t work”? You probably just need to show
the plot inside your loop. See the docs (specifically the page on “output”)


#3

Hi cortner, I would use Plots.jl for anything fancy, but I sometimes use this solution for quick and dirty “animations”

using PyPlot
x = linspace(0, 2*pi, 100) |> collect 
dt, nsteps = 0.03, 30
fig = figure()
for n = 1:nsteps
    plot(x, sin(x - dt*n), animated=true)
    sleep(0.3)
    IJulia.clear_output(true)
    display(fig)
    clf()
end

#4

@tbreloff Thank you for pointing that out; embarrassingly I didn’t actually see this (I was only following the discussion groups to see whether somebody brings it up)

I now tried both default(show=true) and display(plt) and neither worked for me. With PyPlot nothing happens at all, while with Plotly it will overwrite the existing plot instead of replacing it. Probably there will be a way to fix either - I’ll go read you docs in detail. (But if somebody has seen this and knows the fix I’d love to hear it)

EDIT: if I use GR, then the kernel either crashes or I see nothing?


#5

@cstjean Thank you - this seems to work. Good to know there is such a simple solution.

The only problem with IJulia.clear_output(true) is that it creates very strong flickering, so not very useful for presentations.


#6

The following example works on macOS, Linux and Windows:

using GR
inline()
x = linspace(0, 2*pi, 100)
dt, nsteps = 0.03, 30
for n = 1:nsteps
    plot(x, sin(x - dt*n))
end

Can also be used in iTerm2 or Atom (inline("iterm"), inline("atom") resp.).

If you observe some flickering (in non-GUI mode), simple enable double buffering …

ENV["GKS_DOUBLE_BUF"]="true"
```

... before importing ``GR``.

Using ``gr()`` via ``Plots`` should also work.

#7

@jheinen Copy pasting your code into my notebook, I get no output at all. I am beginning to wonder whether there is something wrong with my installation . . .


#8

Sounds fishy. Update, build, and restart?


#9

Sorry. There is sth going wrong. Right now, it only works when creating a movie on the fly. That’s probably not what you want …

I’ll check that.

using GR
inline("mov")
x = linspace(0, 2*pi, 100)
dt, nsteps = 0.03, 30
for n = 1:nsteps
    plot(x, sin(x - dt*n))
end
GR.show()

#10

GKS: /home/kjwiik/.julia/v0.5/GR/src/…/deps/gr/lib/./movplugin.so: undefined symbol: gks_movplugin


#11

This problem is solved with the actual GR release …

Pkg.update()
ENV["GRDIR"]=""
Pkg.build("GR")

… should update GR to 0.18.0 and download the GR run-time (0.22.0).


#12

Thanks, now there are no errors but the movie is empty…


#13

I get the same result


#14

The following code, which modifies @cstjean’s suggestion works perfectly:

using Plots
Plots.plotlyjs()
x = linspace(0, 2*pi, 100) |> collect 
dt, nsteps = 0.03, 100
for n = 1:nsteps
    IJulia.clear_output(true)
    Plots.plot(x, sin(x - n*dt))  |> display
end

Replacing Plotly backend with GR works equally well. With PyPlot is just slow and flickers.

Thank you all for the help - I am very happy that this works.


#15

there is just one nagging little issue left: the notebook freezes during the animation (i.e. I can’t scroll, type or do anything else) Is this avoidable and if so where could I raise it as an issue?


#16

This should not be necessary. There must be some issue with the IJulia integration?


#17

So this is the code that works fine ith GR:

using GR
inline()
x = linspace(0, 2*pi, 100) |> collect 
dt, nsteps = 0.03, 100
for n = 1:nsteps
    IJulia.clear_output(true)
    plot(x, sin(x - n*dt))  |> display
end

There should be some GR option (in the next release) to avoid the IJulia.clear_output() call.

BTW: It seems to me, that the PlotlyJS solution is somehow buffered and not plotting in real-time.


#18

@mkborregaard What should not be necessary?


#19

the clear_output() call


#20

Did GR create a file gks.mov in your working directory? If so, can you play it using ffplay or vlc. If not, what system (OS, version) are you using?

Does the version I posted 1h ago work?