matplotlibanimationjuliajulia-plots

How to make an animation using PyPlot.jl with multiple axes?


I would like to create an animation of two axes. In the simple example illustrated below, I would like to plot two matrices using imshow as a function of time.

Coming from python, I would create an animation using matplotlib.animation similar to this:

using PyCall
@pyimport matplotlib.animation as anim
using PyPlot
import IJulia

A = randn(20,20,20,2)

fig, axes = PyPlot.subplots(nrows=1, ncols=2, figsize=(7, 2.5))
ax1, ax2 = axes

function make_frame(i)
    ax1.clear()
    ax2.clear()
    ax1.imshow(A[:,:,i+1, 1])
    ax2.imshow(A[:,:,i+1, 2])
end

withfig(fig) do
    myanim = anim.FuncAnimation(fig, make_frame, frames=size(A,3), interval=20, blit=false)
    myanim[:save]("test.mp4", bitrate=-1, extra_args=["-vcodec", "libx264", "-pix_fmt", "yuv420p"])
end

This however just creates a blank animation. Do I need to use an init_func in the FuncAnimation? Do I need to enable blitting? Or can I update the artist using a set_data attribute?


Solution

  • Don't use IJulia for this routine. If you plan to include the routine in a notebook, just run the code and then view the file you create, without using withfig. withfig is causing your animation creation to abort for some reason, probably because it expects something within an IJulia environment to be set differently.

    This works:

    using PyCall
    @pyimport matplotlib.animation as anim
    using PyPlot
    
    A = randn(20,20,20,2)
    fig, axes = PyPlot.subplots(nrows=1, ncols=2, figsize=(7, 2.5))
    ax1, ax2 = axes
    
    function make_frame(i)
        ax1.clear()
        ax2.clear()
        ax1.imshow(A[:,:,i+1, 1])
        ax2.imshow(A[:,:,i+1, 2])
    end
    
    myanim = anim.FuncAnimation(fig, make_frame, frames=size(A,3), interval=20, blit=false)
    myanim[:save]("test.mp4", bitrate=-1, extra_args=["-vcodec", "libx264", "-pix_fmt", "yuv420p"])
    # now you can call your video viewer on "test.mp4"