6.5 绘制酷炫的gif动态图¶
6.5.1 准备工作¶
在 Jupyter Notebook 里要对动态图进行保存,需要 ImageMagick
这个超强大的图形处理软件的支持。
所以在往下学习之前,你需要先安装这个工具。安装方法请自行搜索引擎解决哈。
安装完成后,请打开 CMD 终端,检验一下是否成功安装,如果执行没有报错,则已成功安装。
magick --version
6.5.2 绘制原理¶
首先,我们要清楚的是,matplotlib
只能对静态图进行绘制展示。那么动态图是如何实现的?动态图和视频一样,都是由一帧一帧的画面组合而成。将这些画面拼接起来的工作,就是由
ImageMagick
来完成的。
问题又来了,如何在程序里可以生成这些一帧一帧的画面呢?
matplotlib 给我们提供了一个函数,animation.FuncAnimation
用它我们就可以很轻松的完成这些画面展示。最后才能交由 ImageMagick
来处理。
接下来,来看看绘制的整体代码框架(伪代码)。
# 导入相关模块
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Image
from matplotlib.animation import FuncAnimation
# 生成数据(用于传入updata函数)
def data_gen():
pass
# 初始化图像(譬如 坐标范围)
def init():
pass
# 将最新数据添加到图像中
def update(data):
pass
# 核心方法入口
ani = FuncAnimation()
# 保存 gif 动态图
ani.save('ming.gif',writer=writer)
# 将 gif 图展示在页面上
Image(url='./ming.gif')
6.5.3方法参数¶
本节最重要的知识点,其实就一个函数(FuncAnimation
),他可以接收很多参数。要使用它,必须得先知道这些参数都有什么用途。
fig
:进行动画绘制的figureinit_func
:自定义开始帧,即传入刚定义的函数initinterval
:更新频率,以ms计。blit
:选择更新所有点,还是仅更新产生变化的点。应选择True。func
:接收来自 frames 函数传来的 frame 值,作为更新图像最新数据。frames
:可接收对象有 iterable, int, generator function, or None。用途生成数据传递给func函数
6.5.4 实战讲解¶
经过我的一番尝试,发现在 Notebook 无法直接使用ImageMagick
。
我们必须显式地指定其路径,并生成一个 ImageMagickFileWriter 实例,用于后面保存图像使用。
import matplotlib.pyplot as plt
plt.rcParams['animation.convert_path'] = \
'E:\Program Files\ImageMagick-7.0.8-Q16\magick.exe'
from matplotlib.animation import ImageMagickFileWriter
writer = ImageMagickFileWriter()
具体绘制代码如下。
# 导入相关模块
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Image
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
xdata, ydata = [], []
# 注意这边的 "," 不能省
ln, = ax.plot([], [], 'r-', animated=False)
# 初始化图像(譬如 坐标范围)
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1.1, 1.1)
# 注意这边的 "," 也不能省
return ln,
# 将最新数据添加到图像中
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
# 注意这边的 "," 也不能省
return ln,
# 核心方法入口
ani = FuncAnimation(fig,
update,
frames=np.linspace(0, 2*np.pi, 50),
interval=5,
init_func=init,
blit=True)
# 保存 gif 动态图
ani.save('ming.gif',writer=writer)
# 将 gif 图展示在页面上
Image(url='./ming.gif')
绘制出来的结果如下: