文章目录
- 示例
- FuncAnimation
- 三维情况
示例
matplotlib
中的animation
提供了动态绘图功能,下面列举一个最简单的动态绘制三角函数的例子,来初步演示一下。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots(figsize=(5,3))
line, = ax.plot([], [], lw=1)
ax.grid()
def init():
ax.set_ylim(-1, 1)
ax.set_xlim(0, 10)
line.set_data([],[])
plt.tight_layout()
return line,
def animate(N):
x = np.arange(N)/10
y = np.sin(x)
line.set_data(x, y)
return line,
ani = animation.FuncAnimation(fig, animate, range(100), init_func=init, interval=40)
ani.save("ani_test_0.gif")
plt.show()
效果如下
其中,fig, ax
为绘图窗口和坐标轴,这是在任何绘图操作中都涉及到的元素,但在本例中的动态绘图操作中,ax
是以一种"全局变量"的形式存在的,将在后米娜的init
和animate
函数中被直接调用。
line
即为绘制在ax
之上的曲线,由于ax.plot
默认返回一个曲线列表,通过line,=
这样的方法,可以提取出曲线列表中的第0条曲线,其结果等价于
line = ax.plot([], [], lw=1)[0]
接下来init
函数用于绘图曲线的初始化,animate
用于调整绘图函数的动态变化,其输入N
暂时可以简单地理解为第N
张图像的曲线。
接下来,就是动态绘图的核心对象FuncAnimation
。
FuncAnimation
FuncAnimation
是一个类,其构造函数为
FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)
前面的4个参数在示例程序中已经用到,fig
为绘图窗口;func
为图像更新函数;frames
为绘图帧号;init_func
为图像的初始化函数。
其绘图逻辑写成伪代码类似于
for n in frames:
if n>0:
draw(func(n))
else:
draw(init(n))
如果frames
是一个整数,则在调用时会自动转为range(frames)
。
而用于绘图的主要对象,就是坐标轴ax
,故而在示例中的animate
以及init
函数的返回对象是line,
,当然也可以写成return [line]
。
FuncAnimation
中的其他参数含义如下:
fargs
为绘图函数func
的其他输入参数save_count
缓存帧数interval
帧延时,默认200毫秒,帧率25fps对应40毫秒。repeat_delay
重复延时,单位是微秒repeat
为False
时,动画将只演示一遍。
三维情况
三维情况的动图绘制函数,机理与二维是相同的,下面引用官方画廊中的示例,来演示一下三维动图的绘制流程,首先生成一组随机行走的曲线
np.random.seed(19680801) # 随机数种子,便于复现
def random_walk(N, L=0.05):
st = np.random.random(3)
steps = np.random.uniform(-L, L, size=(N, 3))
walk = st + np.cumsum(steps, axis=0)
return walk
walks = [random_walk(30) for index in range(40)]
random_walk
可生成一条随机行走的三维曲线,walks
通过调用这个函数,共生成了40条曲线,下面就是对这40条曲线的调用
def animate(num, walks, lines):
for line, walk in zip(lines, walks):
line.set_data(walk[:num, :2].T)
line.set_3d_properties(walk[:num, 2])
return lines
fig = plt.figure(figsize=(5,4))
ax = fig.add_subplot(projection="3d")
lines = [ax.plot([], [], [], lw=1)[0] for _ in walks]
ax.set(xlim3d=(0, 1), xlabel='X')
ax.set(ylim3d=(0, 1), ylabel='Y')
ax.set(zlim3d=(0, 1), zlabel='Z')
ani = animation.FuncAnimation(
fig, animate, 30, fargs=(walks, lines), interval=100)
plt.show()
效果如下