前面学习了回调函数animation.FuncAnimation方式来创建动画,这种方式是有很大的优势,因为它是按需地更新数据,而不需要一次性地生成所有的数据,这样占用内存资源是比较小的,当然它也是有一定的不足之处,当数据计算量大时,就会影响动画的输出速度。如果对动画的输出有速度的要求,或者说帧速度比较严格的,就可以采用另外一种方式,就是艺术家方式ArtistAnimation。它刚好与回调方式相反,需要预先生成动画每一帧的数据,然后一次性输入给ArtistAnimation对象,它就会把整个动画数据一帧一帧地播放出来,减少了数据的计算量。这两种方式都是可以生成动画,具体看自己的需求,那种方式可以满足,就采用那种方法。
下面就来通过例子来演示艺术家方式ArtistAnimation的动画实现过程。先来看一下这个类的定义:
matplotlib.animation.ArtistAnimation(fig, artists, *args, **kwargs)
- 第一个参数fig是绘图用的画布,主要用来显示图像和缩放大小。
-
第二个参数artists是表示每个帧绘图数据显示的对象列表,程序里会遍历列表,每一项生成一帧动画帧。
-
第三个参数interval是每帧延时时间,与前面的回调函数一样的。
-
第四个参数repeat_delay是表示重复播放动画之间中的延时,默认是0毫秒。
-
第五个参数repeat是表示是否播放动画完之后重复播放,当设置True时表示重复播放,默认为重复播放。
-
第六个参数blit是表示是否使用优化机制,与前面回调函数的意义一样。
有了这个类的说明,以及参数的定义,就可以编写程序了。
ims = []
for i in range(20):
rand = np.random.randn(100) # 100个随机数生成
im = ax.plot(rand) # 显示100数据
ims.append(im) # 保存到列表
这段代码先定义一个列表ims,然后生成20帧的数据,每帧数据由随机数生成100个数据点,然后调用ax.plot把这100个点连接起来,形成曲线。再把显示对象im保存到列表里,以便传送给艺术家对象生成动画。
anim = animation.ArtistAnimation(fig, ims, interval=100)
这行代码,就是调用艺术家对象生成动画。
FFwriter = animation.FFMpegWriter(fps=20, extra_args=['-vcodec', 'libx264'],
metadata = {'title':'demo', 'artist':'极客笔记'})
anim.save('ani-054.mp4', writer = FFwriter)
这两行代码,用来生成MP4文件,增加一些描述数据,以便写到MP4文件里。
运行的结果显示如下:
整个例子的代码如下:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
plt.rcParams['animation.ffmpeg_path'] = r'D:\ffmpeg-2020-12-20\bin\ffmpeg.exe'
# 创建绘图轴对象
fig, ax = plt.subplots()
# 生成动画绘制所有数据
ims = []
for i in range(20):
rand = np.random.randn(100) # 100个随机数生成
im = ax.plot(rand) # 显示100数据
ims.append(im) # 保存到列表
anim = animation.ArtistAnimation(fig, ims, interval=100)
#保存的动画视频文件名为当前文件夹下的ani-054.mp4,帧率为20帧每秒,格式为MP4。
FFwriter = animation.FFMpegWriter(fps=20, extra_args=['-vcodec', 'libx264'],
metadata = {'title':'demo', 'artist':'蔡军生'})
anim.save('ani-054.mp4', writer = FFwriter)
plt.show() # 会一直循环播放动画