matplotlib:利用FuncAnimation类生成简易逐帧动画
程序员文章站
2022-02-05 19:27:05
...
当前有效matplotlib
版本为:3.4.1
。
概述
逐帧动画(Frame By Frame)是一种常见的动画形式,通过将不同的静止图像以一定时间间隔连续播放,因人类视觉暂停现象而获得动画的效果。
FuncAnimation
是matplotlib
生成逐帧动画的常用类,它的工作原理就是按照一定时间间隔不断调用参数func
对应的函数生成动画。
FuncAnimation
的继承关系如下:matplotlib.animation.Animation→matplotlib.animation.TimedAnimation→matplotlib.animation.FuncAnimation
FuncAnimation
类的签名为:class matplotlib.animation.FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)
构造函数参数如下:
-
fig
:承载动画的图形对象。matplotlib.figure.Figure
对象。必备参数。 -
func
: 每一帧都需要调用的函数。可调用对象。必备参数。func
的签名如下为def func(frame, *fargs) -> iterable_of_artists
。第一个参数为frames
参数传递过来的一个元素,剩余位置参数由fargs
参数提供。
如果blit == True
,func
必须返回一个包含所有已创建或修改的可视化对象(artist)的可迭代对象。如果blit == False
,返回值将被忽略。 -
frames
:用于向func
生成的每一帧传递一个值。可迭代对象,整数,生成器或None
,可选参数。- 如果值为可迭代对象,直接使用可迭代对象。如果可迭代对象长度固定,将会覆盖
save_count
参数。 - 如果值为整数,相当于传递
range(frames)
。 - 如果值为生成器,生成器的签名要求为
def gen_function() -> obj
。 - 如果值为
None
,相当于传递itertools.count
。
- 如果值为可迭代对象,直接使用可迭代对象。如果可迭代对象长度固定,将会覆盖
-
init_func
: 用于初始化帧的函数,在生成第1帧之前,会调用一次该函数。可调用对象。可选参数。如果不提供改参数, 将使用frames
参数中的第一个元素的绘制结果。该参数的签名要求为def init_func() -> iterable_of_artists
,除了参数,其余要求与func
参数类似。 -
fargs
: 传递给func
的附加参数。元组或None
。可选参数。 -
save_count
: 用于缓存frames
值的数量,该参数只用于frames
值数量不能推断出的情况。整数。默认值为100
-
interval
:帧之间的间隔毫秒数。整数。默认值为200
。 -
repeat_delay
:当repeat
为True
时生效。即动画重复执行的间隔毫秒数。当整数。默认值为0
。 -
repeat
:当帧序列执行一次之后是否重复执行。布尔值。默认值为True
。 -
blit
: 是否采用按叠放次序(zorder)优化绘图模式。布尔值。默认值为False
。 -
cache_frame_data
:每帧数据是否被缓存。布尔值。默认值为True
。
FuncAnimation
类继承了matplotlib.animation.Animation
类的pause
和resume
方法,可实现动画的暂停和继续功能。
案例1:动态绘制sin曲线
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
# 构造空线条
line, = ax.plot([], [])
# 构造线条数据结构
xdata, ydata = [], []
# 设置坐标轴刻度范围
ax.set_ylim(-1.1, 1.1)
ax.set_xlim(0, 50)
# 动画循环一次后进行初始化,清空数据
def init():
del xdata[:]
del ydata[:]
line.set_data(xdata, ydata)
return line,
# 控制每帧画面如何绘制
def update(x):
y = np.sin(x)
xdata.append(x)
ydata.append(y)
xmin, xmax = ax.get_xlim()
line.set_data(xdata, ydata)
fig.canvas.draw()
return line,
ani = animation.FuncAnimation(fig, update, 50, interval=10, init_func=init)
plt.show()
案例2:点击鼠标左键暂停/继续动画
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
# 构造空线条
line, = ax.plot([], [])
# 构造线条数据
n = 50
x = np.arange(n)
y = np.sin(x)
# 设置坐标轴刻度范围
ax.set_ylim(-1.1, 1.1)
ax.set_xlim(0, n)
# 控制每帧画面如何绘制
def update(i):
line.set_data(x[:i], y[:i])
return line,
ani = animation.FuncAnimation(fig, update, n, interval=10,)
# 事件处理
paused = False
def toggle_pause(event):
global paused
if paused:
ani.resume()
else:
ani.pause()
paused = not paused
fig.canvas.mpl_connect('button_press_event', toggle_pause)
plt.show()
上一篇: 使用Matplotlib绘制3D动画