备注
Go to the end 下载完整的示例代码.
使用 Matplotlib 的动画#
Matplotlib 基于其绘图功能,还提供了一个接口来使用 animation 模块生成动画.动画是由一系列帧组成的,其中每一帧对应于 Figure 上的一个绘图.本教程涵盖了如何创建此类动画以及可用选项的一般指南.更多信息请参见 API 描述:animation
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
动画类#
Matplotlib 中的动画过程可以被认为是两种不同的方式:
FuncAnimation:为第一帧生成数据,然后修改每一帧的数据以创建动画图.ArtistAnimation:生成一个艺术家列表(可迭代的),这些艺术家将在动画的每一帧中绘制.
FuncAnimation 在速度和内存方面更有效,因为它绘制一次艺术家,然后修改它.另一方面, ArtistAnimation 很灵活,因为它允许任何艺术家的可迭代对象按顺序进行动画处理.
FuncAnimation#
FuncAnimation 类允许我们通过传递一个迭代地修改绘图数据的函数来创建动画.这是通过使用各种 Artist 上的 setter 方法来实现的(示例:Line2D , PathCollection 等).通常, FuncAnimation 对象接受我们想要动画的 Figure 和一个修改图形上绘制的数据的函数 func.它使用 frames 参数来确定动画的长度.interval 参数用于确定绘制两帧之间的时间(以毫秒为单位).使用 FuncAnimation 进行动画处理通常需要以下步骤:
像在静态图中一样绘制初始图形.将 plot 函数返回的所有已创建的艺术家保存在变量中,以便您以后可以在动画函数中访问和修改它们.
创建一个动画函数,用于更新给定帧的艺术家.通常,这会调用艺术家的
set_*方法.创建一个
FuncAnimation,传递Figure和动画函数.使用以下方法之一保存或显示动画:
pyplot.show在窗口中显示动画Animation.to_html5_video创建 HTML<video>标签Animation.to_jshtml创建带有交互式 JavaScript 动画控件的 HTML 代码Animation.save将动画保存到文件
下表显示了一些绘图方法,它们返回的艺术家以及一些常用的 set_* 方法,这些方法用于更新底层数据.虽然更新数据是动画中最常见的操作,但您也可以更新其他方面,例如颜色或文本位置.
绘图方法 |
艺术家 |
数据设置方法 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
涵盖所有类型的艺术家的 set 方法超出了本教程的范围,但可以在它们各自的文档中找到.以下是 Axes.scatter 和 Axes.plot 中使用的此类更新方法的示例.
fig, ax = plt.subplots()
t = np.linspace(0, 3, 40)
g = -9.81
v0 = 12
z = g * t**2 / 2 + v0 * t
v02 = 5
z2 = g * t**2 / 2 + v02 * t
scat = ax.scatter(t[0], z[0], c="b", s=5, label=f'v0 = {v0} m/s')
line2 = ax.plot(t[0], z2[0], label=f'v0 = {v02} m/s')[0]
ax.set(xlim=[0, 3], ylim=[-4, 10], xlabel='Time [s]', ylabel='Z [m]')
ax.legend()
def update(frame):
# for each frame, update the data stored on each artist.
x = t[:frame]
y = z[:frame]
# update the scatter plot:
data = np.stack([x, y]).T
scat.set_offsets(data)
# update the line plot:
line2.set_xdata(t[:frame])
line2.set_ydata(z2[:frame])
return (scat, line2)
ani = animation.FuncAnimation(fig=fig, func=update, frames=40, interval=30)
plt.show()
ArtistAnimation#
如果数据存储在各种不同的艺术家上,则可以使用 ArtistAnimation 来生成动画.然后,此艺术家列表会逐帧转换为动画.例如,当我们使用 Axes.barh 绘制条形图时,它会为每个条和误差条创建许多艺术家.要更新绘图,需要单独更新容器中的每个条,然后重新绘制它们.相反, animation.ArtistAnimation 可用于单独绘制每一帧,然后将它们拼接在一起以形成动画.条形图赛跑就是一个简单的例子.
fig, ax = plt.subplots()
rng = np.random.default_rng(19680801)
data = np.array([20, 20, 20, 20])
x = np.array([1, 2, 3, 4])
artists = []
colors = ['tab:blue', 'tab:red', 'tab:green', 'tab:purple']
for i in range(20):
data += rng.integers(low=0, high=10, size=data.shape)
container = ax.barh(x, data, color=colors)
artists.append(container)
ani = animation.ArtistAnimation(fig=fig, artists=artists, interval=400)
plt.show()
动画编写器#
动画对象可以使用各种多媒体编写器(例如:Pillow,ffpmeg,imagemagick)保存到磁盘.并非所有视频格式都受所有编写器支持.主要有 4 种类型的编写器:
PillowWriter- 使用 Pillow 库创建动画.HTMLWriter- 用于创建基于 JavaScript 的动画.基于管道的编写器 -
FFMpegWriter和ImageMagickWriter是基于管道的编写器.这些编写器将每一帧通过管道传输到实用程序(ffmpeg / imagemagick),然后将所有帧拼接在一起以创建动画.基于文件的编写器 -
FFMpegFileWriter和ImageMagickFileWriter是基于文件的编写器的示例.这些编写器比基于管道的替代方案慢,但对于调试更有用,因为它们在将每帧拼接成动画之前先将其保存在文件中.
保存动画#
编写器 |
支持的格式 |
|---|---|
|
.gif, .apng, .webp |
|
.htm, .html, .png |
FFMpegWriterFFMpegFileWriter |
ffmpeg 支持的所有格式: |
ImageMagickWriterImageMagickFileWriter |
imagemagick 支持的所有格式: |
要使用任何编写器保存动画,我们可以使用 animation.Animation.save 方法.它接受我们要将动画保存为的文件名和编写器,编写器可以是字符串或编写器对象.它还接受一个 fps 参数.此参数与 FuncAnimation 或 ArtistAnimation 使用的 interval 参数不同.fps 确定保存的动画使用的帧率,而 interval 确定显示的动画使用的帧率.
以下是一些示例,展示了如何使用不同的编写器保存动画.
Pillow 编写器:
ani.save(filename="/tmp/pillow_example.gif", writer="pillow")
ani.save(filename="/tmp/pillow_example.apng", writer="pillow")
HTML 编写器:
ani.save(filename="/tmp/html_example.html", writer="html")
ani.save(filename="/tmp/html_example.htm", writer="html")
ani.save(filename="/tmp/html_example.png", writer="html")
FFMpegWriter:
ani.save(filename="/tmp/ffmpeg_example.mkv", writer="ffmpeg")
ani.save(filename="/tmp/ffmpeg_example.mp4", writer="ffmpeg")
ani.save(filename="/tmp/ffmpeg_example.mjpeg", writer="ffmpeg")
Imagemagick 编写器:
ani.save(filename="/tmp/imagemagick_example.gif", writer="imagemagick")
ani.save(filename="/tmp/imagemagick_example.webp", writer="imagemagick")
ani.save(filename="apng:/tmp/imagemagick_example.apng",
writer="imagemagick", extra_args=["-quality", "100"])
(apng 的 extra_args 是必需的,以将文件大小减少约 10 倍)
请注意,ffmpeg 和 imagemagick 需要单独安装.获取 ffmpeg 的一种跨平台方法是安装 imageio_ffmpeg PyPI 包,然后设置 rcParams["animation.ffmpeg_path"] = imageio_ffmpeg.get_ffmpeg_exe() .
脚本的总运行时间:(0 分钟 10.303 秒)