Matplotlib 简明教程
Matplotlib - Animations
Animation 是一种视觉技术,它涉及通过一系列单帧创建动态图像。每帧表示时间中的特定时刻,当以高速连续播放时,会创建移动的幻觉。例如,动画对象的常见示例是 GIF。示例如下 −
动画的流行文件格式有 GIF、APNG(动画可移植网络图形)、mkv、mp4 等。
Animations in Matplotlib
Matplotlib 提供了一个专门用于创建动画的模块。在此上下文中,动画是一系列帧,每个帧都与图形上的一幅图相关联。
要将动画能力集成到我们的工作环境中,我们可以使用以下命令导入专用模块 −
import matplotlib.animation as animation
Creating Animations
在 Matplotlib 中创建动画可以通过两种不同的方法来完成。matplotlib.animation 模块为此提供了两个主要类 −
-
FuncAnimation
-
ArtistAnimation
The FuncAnimation class
使用 FuncAnimation 类的做法是一种高效的方式,可以通过修改每帧的绘图数据来创建动画。它允许我们通过传递一个用户定义的函数来创建动画,该函数迭代修改绘图数据。该类涉及生成初始帧的数据,随后修改此数据以用于每个后续帧。
此示例演示了使用 FuncAnimation 类对正弦波绘图进行动画,演示对象的运动。它还使用 Matplotlib 动画更新 X 轴值。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
# Creating a figure and axis
fig, ax = plt.subplots(figsize=(7, 4))
# Generating x values
x = np.arange(0, 2*np.pi, 0.01)
# Plotting the initial sine curve
line, = ax.plot(x, np.sin(x))
ax.legend([r'$\sin(x)$'])
# Function to update the plot for each frame of the animation
def update(frame):
line.set_ydata(np.sin(x + frame / 50))
ax.set_xlim(left=0, right=frame)
return line
# Creating a FuncAnimation object
ani = animation.FuncAnimation(fig=fig, func=update, frames=40, interval=30)
# Displaying the output
plt.show()
以上示例生成以下输出 −
这里有另一个示例,它使用 FuncAnimation 类创建了一个动画的 3D 曲面图。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# Generate data
N = 50
fps = 250
frn = 75
x = np.linspace(-2, 2, N + 1)
x, y = np.meshgrid(x, x)
zarray = np.zeros((N + 1, N + 1, frn))
f = lambda x, y, sig: 1 / np.sqrt(sig) * np.exp(-(x ** 2 + y ** 2) / sig ** 2)
# Create data array
for i in range(frn):
zarray[:, :, i] = f(x, y, 1.5 + np.sin(i * 2 * np.pi / frn))
# Update plot function
def change_plot(frame_number, zarray, plot):
plot[0].remove()
plot[0] = ax.plot_surface(x, y, zarray[:, :, frame_number], cmap="afmhot_r")
# Create figure and subplot
fig = plt.figure(figsize=(7, 4))
ax = fig.add_subplot(111, projection='3d')
# Initial plot
plot = [ax.plot_surface(x, y, zarray[:, :, 0], color='0.75', rstride=1, cstride=1)]
# Set axis limits
ax.set_zlim(0, 1.1)
# Animation
ani = animation.FuncAnimation(fig, change_plot, frn, fargs=(zarray, plot), interval=1000 / fps)
# Turn off axis and grid
ax.axis('off')
ax.grid(False)
# Show plot
plt.show()
以上示例生成以下输出 −
ArtistAnimation
ArtistAnimation 是一种灵活的方法,适用于需要按顺序对不同的艺术家进行动画的场景。此方法涉及生成一个艺术家列表(可迭代),将它们绘制到动画的每帧中。
此示例演示了使用 ArtistAnimation 类创建动画。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
# Create a figure and axis
fig, ax = plt.subplots(figsize=(7,4))
# Define the function
def f(x, y):
return np.sin(x) + np.cos(y)
# Generate x and y values for the function
x = np.linspace(0, 2 * np.pi, 180)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
# ims is a list of lists, each row is a list of artists to draw in the current frame
ims = []
# Generate frames for the animation
for i in range(60):
x += np.pi / 10
y += np.pi / 30
im = ax.imshow(f(x, y), animated=True)
if i == 0:
ax.imshow(f(x, y)) # show an initial one first
ims.append([im])
# Create an ArtistAnimation with the specified interval, blit, and repeat_delay
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000)
# Display the animation
plt.show()
上面的代码生成了以下结果 −
Saving animations
可以使用不同的多媒体编写器(如 Pillow、ffmpeg 和 imagemagick)将动画对象保存到磁盘。但是,需要注意的是,并非所有视频格式都受每个编写器支持。编写器主要有四种类型:
-
PillowWriter
-
HTMLWriter
-
Pipe-based writers
-
File-based writers
PillowWriter
它使用 Pillow 库以 GIF、APNG 和 WebP 等各种格式保存动画。
一个示例演示了对散点图进行动画并使用 PillowWriter 将其保存为 GIF。
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
# Generate data
steps = 50
nodes = 100
positions = []
solutions = []
for i in range(steps):
positions.append(np.random.rand(2, nodes))
solutions.append(np.random.random(nodes))
# Create a figure and axes
fig, ax = plt.subplots(figsize=(7, 4))
marker_size = 50
# Function to update the plot for each frame of the animation
def animate(i):
fig.clear()
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(0, 1), ylim=(0, 1))
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
s = ax.scatter(positions[i][0], positions[i][1], s=marker_size, c=solutions[i], cmap="RdBu_r", marker="o", edgecolor='black')
plt.grid(None)
# Creating a FuncAnimation object
ani = animation.FuncAnimation(fig, animate, interval=100, frames=range(steps))
# Save the animation as a GIF using the PillowWriter
ani.save('animation.gif', writer='pillow')
如果您访问保存输出的文件夹,可以看到以下 gif 文件 −
Pipe-based writers
这些编写人员使用诸如 FFMpegWriter 和 ImageMagickWriter 之类的外部实用程序来创建动画。它们支持各种视频格式,并将帧传输到该实用程序,该实用程序将它们拼接在一起以创建动画。
File-based writers
基于文件的编写器(FFMpegFileWriter 和 ImageMagickFileWriter)稍慢,但提供在创建最终动画之前保存每个帧的优点。
以下示例展示了如何正确为 matplotlib.animation 启用 ffmpeg 。在此,使用动画图像矩阵和动画彩色条创建绘图。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.axes_grid1 import make_axes_locatable
plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True
plt.rcParams['animation.ffmpeg_path'] = 'ffmpeg'
fig = plt.figure()
ax = fig.add_subplot(111)
div = make_axes_locatable(ax)
cax = div.append_axes('right', '5%', '5%')
data = np.random.rand(5, 5)
im = ax.imshow(data)
cb = fig.colorbar(im, cax=cax)
tx = ax.set_title('Frame 0')
cmap = ["copper", 'RdBu_r', 'Oranges', 'cividis', 'hot', 'plasma']
def animate(i):
cax.cla()
data = np.random.rand(5, 5)
im = ax.imshow(data, cmap=cmap[i%len(cmap)])
fig.colorbar(im, cax=cax)
tx.set_text('Frame {0}'.format(i))
ani = animation.FuncAnimation(fig, animate, frames=10)
FFwriter = animation.FFMpegWriter()
ani.save('plot.mp4', writer=FFwriter)
执行上述代码时,您将获得以下输出 -