Animations in Julia by PyPlot and matplotlib.animation

In [1]:
using PyPlot
using PyCall
@pyimport matplotlib.animation as anim

#Construct Figure and Plot Data
fig = figure("MyFigure",figsize=(5,5))
ax = axes(xlim = (0,10),ylim=(0,10))
global line1 = ax[:plot]([],[],"r-")[1]
global line2 = ax[:plot]([],[],"g-")[1]
global line3 = ax[:plot]([],[],"b-")[1]

# Define the init function, which draws the first frame (empty, in this case)
function init()
    global line1
    global line2
    global line3
    line1[:set_data]([],[])
    line2[:set_data]([],[])
    line3[:set_data]([],[])
    return (line1,line2,line3,Union{})  # Union{} is the new word for None
end

# Animate draws the i-th frame, where i starts at i=0 as in Python.
function animate(i)
    global line1
    global line2
    global line3
    x = (0:i)/10.0
    line1[:set_data](x,x)
    line2[:set_data](1+x,x)
    line3[:set_data](2+x,x)
    return (line1,line2,line3,Union{})
end

# Create the animation object by calling the Python function FuncAnimaton
myanim = anim.FuncAnimation(fig, animate, init_func=init, frames=100, interval=20)

# Convert it to an MP4 movie file and saved on disk in this format.
#myanim[:save]("3Lines.mp4", bitrate=-1, extra_args=["-vcodec", "libx264", "-pix_fmt", "yuv420p"])
myanim[:save]("test1.mp4", bitrate=-1, extra_args=["-vcodec", "libx264", "-pix_fmt", "yuv420p"])
    
# Function for creating an embedded video given a filename
function html_video(filename)
    open(filename) do f
        base64_video = base64encode(f)
        """<video controls src="data:video/x-m4v;base64,$base64_video">"""
    end
end

# Display the movie in a Julia cell as follows. Note it has animation controls for the user.
#display("text/html", html_video("3Lines.mp4"))
display("text/html", html_video("test1.mp4"))
In [2]:
using PyCall
@pyimport matplotlib.animation as anim
using PyPlot

function showanim(filename)
    base64_video = base64encode(open(filename))
    display("text/html", """<video controls src="data:video/x-m4v;base64,$base64_video">""")
end

A = randn(20,20,20)

fig = figure(figsize=(2,2))

function make_frame(i)
    imshow(A[:,:,i+1],interpolation="none")
end

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

showanim("test2.mp4")

Example 3

Python code

"""
A simple example of an animated plot
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax = plt.subplots()

x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))


def animate(i):
    line.set_ydata(np.sin(x + i/10.0))  # update the data
    return line,


# Init only required for blitting to give a clean slate.
def init():
    line.set_ydata(np.ma.array(x, mask=True))
    return line,

ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,
                              interval=25, blit=True)
plt.show()
In [3]:
using PyCall
@pyimport matplotlib.animation as anim
using PyPlot

function showanim(filename)
    base64_video = base64encode(open(filename))
    display("text/html", """<video controls src="data:video/x-m4v;base64,$base64_video">""")
end

fig = figure(figsize=(4,4))
ax = axes()

x = [0:0.01:2pi;]

# i=0,1,...,frames-1
function animate(i)
    clf()
    plot(sin.(x+i/10.0))
end

function init()
    plot(x,sin.(x))
end

withfig(fig) do
    myanim = anim.FuncAnimation(fig, animate, frames=200, init_func=init, interval=25, blit=true)
    myanim[:save]("test3.mp4", bitrate=-1, extra_args=["-vcodec", "libx264", "-pix_fmt", "yuv420p"])
end

showanim("test3.mp4")
error in running finalizer: Base.ArgumentError(msg="ref of NULL PyObject")

Example 4

上の Example 3 とこの Example 4 はどうしてこれでうまく行くのか理解していない。

In [4]:
using PyCall
@pyimport matplotlib.animation as anim
using PyPlot

function showmp4(filename)
    open(filename) do f
        base64_video = base64encode(f)
        display("text/html", """<video controls src="data:video/x-m4v;base64,$base64_video">""")
    end
end

fig = figure()
ax = axes()

x = [-1.5:0.05:1.0;]
y = [-1.0:0.05:1.0;]
z = x' .+ im*y
w0 = sqrt.(z.+1)./z

# plotw has period 1:
# plotw(t+1) == plotw(1)
function plotw(t)
    clf()
    title("\$t = $t\$")
    xlim(-1.4,0.9)
    ylim(-0.9,0.9)
    w = exp(pi*im*t)*w0
    streamplot(x,y,real(w),-imag(w))
    axes()[:set_aspect]("equal")
    # quick dirty hack to prevent the following error:
    # TypeError("'StreamplotSet' object is not iterable",)
    plot()
end

n=10 # frame/loop
l=2 # loop
interval=200 # milli seconds

# k=0,1,...,frames-1
function animate(k)
    plotw(k/n)
end

function init()
    plotw(0)
end

withfig(fig) do
    global myanim = anim.FuncAnimation(fig, animate, frames=l*n+1, init_func=init, interval=interval, blit=true)
    myanim[:save]("test4.mp4", bitrate=-1, extra_args=["-vcodec", "libx264", "-pix_fmt", "yuv420p"])
end

showmp4("test4.mp4")

Example 5

Run Imagemagick command to create an animated gif file.

In [5]:
using PyCall
@pyimport matplotlib.animation as anim
using PyPlot

function showgif(filename)
    open(filename) do f
        base64_video = base64encode(f)
        display("text/html", """<img src="data:image/gif;base64,$base64_video">""")
    end
end

fig = figure()
ax = axes()

x = [-1.5:0.05:1.0;]
y = [-1.0:0.05:1.0;]
z = x' .+ im*y
w0 = sqrt.(z.+1)./z

# plotw has period 1.
# plotw(t+1) == plotw(1)
function plotw(t)
    clf()
    title("\$t = $t\$")
    xlim(-1.4,0.9)
    ylim(-0.9,0.9)
    w = exp(pi*im*t)*w0
    streamplot(x,y,real(w),-imag(w))
    axes()[:set_aspect]("equal")
end

n=10 # frame/loop
l=1 # loop
interval=200 # milli seconds

withfig(fig) do
    for k in 1:n*l
        plotw(k/n)
        savefig(@sprintf("test5_%04d",k), bbox_inches="tight")
    end
end

#run(`convert -delay $(interval/10) -loop 0 tmp0\*.png tmp.gif`)
run(`magick -delay $(interval/10) -loop 0 test5_\*.png test5.gif`)

showgif("test5.gif")
error in running finalizer: Base.ArgumentError(msg="ref of NULL PyObject")
In [ ]: