使用Matplotlib轻松制作动画(mp4,gif)


matplotlib.animation:基于matplotlib的便捷动画生成库。

安装

@苹果

1
2
3
$ pip install matplotlib
$ brew install imagemagick # gif 保存用
$ brew install ffmpeg # mp4 保存用

修改matplotlib.rc

1
2
3
4
5
6
7
$ python -c "import matplotlib;print(matplotlib.matplotlib_fname())"
/Users/riki/.pyenv/versions/ML-2.7.13/lib/python2.7/site-packages/matplotlib/mpl-data/matplotlibrc
$ atom /Users/riki/.pyenv/versions/ML-2.7.13/lib/python2.7/site-packages/matplotlib/mpl-data/matplotlibrc

# line 38
- backend : macosx
+ backend : Tkagg

有两种类型的函数可以生成动画

  • ArtistAnimation:预先准备列表中的所有框架
  • FuncAnimation:动态生成每一帧

就个人而言,Artist Animation更容易理解,因此我建议这样做。
FuncAnimation更为灵活,但是我对Artist Animation并没有感到任何不便。

ArtistAnimation

animation.ArtistAnimation(图,艺术家,间隔= 200)
*图:轮廓。 matplotlib图形对象
*艺术家:在每一帧中绘制的艺术家对象(线等)列表的列表
*间隔:每帧的播放间隔[ms]

请注意,在

artists参数必须为list列表的情况下,很容易出现错误。 (详细情况将在后面说明)

示例1:正弦波

的动画

anim_sin_wave.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
x = np.arange(0, 10, 0.1)

ims = []
for a in range(50):
    y = np.sin(x - a)
    line, = plt.plot(x, y, "r")
    ims.append([line])

ani = animation.ArtistAnimation(fig, ims)
ani.save('anim.gif', writer="imagemagick")
ani.save('anim.mp4', writer="ffmpeg")
plt.show()

anim.gif

pyplot.plot函数可以一次绘制多个图形,因此返回类型为list。

1
2
3
4
lines = plt.plot(x1, y1, 'r', x2, y2, 'g', x3, y3, 'b')
print type(lines) # list
print len(lines) # 3
print type(lines[0]) # matplotlib.lines.Line2D

为了清楚起见,我敢于解压缩主要代码以检索Line2D对象,然后将其更改为list,然后将其添加到list。

1
2
line, = plt.plot(x, y, "r")
ims.append([line])

动画可以按如下方式保存(您可以按gif或mp4的方式进行保存)

1
2
ani.save('anim.gif', writer="imagemagick")
ani.save('anim.mp4', writer="ffmpeg")

示例2:2D图像动画

dynamic_image.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()

def f(x, y):
    return np.sin(x) + np.cos(y)

x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
ims = []

for i in range(60):
    x += np.pi / 15.
    y += np.pi / 20.
    im = plt.imshow(f(x, y), animated=True)
    ims.append([im])

ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
                                repeat_delay=1000)

ani.save('anim.gif', writer="imagemagick")
ani.save('anim.mp4', writer="ffmpeg")
plt.show()

anim.gif

由于

pyplot.imshow函数的返回类型是AxesImage对象,因此将其设为列表,然后将其添加到列表中。

1
2
3
im = plt.imshow([[]])
print type(im) # matplotlib.image.AxesImage
ims.append([im])