Matplotlib 简明教程

Matplotlib - Animations

Animation 是一种视觉技术,它涉及通过一系列单帧创建动态图像。每帧表示时间中的特定时刻,当以高速连续播放时,会创建移动的幻觉。例如,动画对象的常见示例是 GIF。示例如下 −

Animation is a visual technique that involves the creation of moving images through a sequence of individual frames. Each frame represents a specific moment in time, and when played consecutively at a high speed, they create the illusion of movement. For instance, a common example of an animated object is a GIF. Here is an example −

animations intro

动画的流行文件格式有 GIF、APNG(动画可移植网络图形)、mkv、mp4 等。

The popular file formats of animations are GIFs, APNG (Animated Portable Network Graphics), mkv, mp4, and more.

Animations in Matplotlib

Matplotlib 提供了一个专门用于创建动画的模块。在此上下文中,动画是一系列帧,每个帧都与图形上的一幅图相关联。

Matplotlib provides a dedicated module for creating animations. In this context, an animation is a series of frames, and each frame is associated with a plot on a Figure.

要将动画能力集成到我们的工作环境中,我们可以使用以下命令导入专用模块 −

To integrate the animation capabilities into our working environment we can import the dedicated module by using the following command −

import matplotlib.animation as animation

Creating Animations

在 Matplotlib 中创建动画可以通过两种不同的方法来完成。matplotlib.animation 模块为此提供了两个主要类 −

Creating animations in Matplotlib can be done through two different approaches. The matplotlib.animation module provides two primary classes for this purpose −

  1. FuncAnimation

  2. ArtistAnimation

The FuncAnimation class

使用 FuncAnimation 类的做法是一种高效的方式,可以通过修改每帧的绘图数据来创建动画。它允许我们通过传递一个用户定义的函数来创建动画,该函数迭代修改绘图数据。该类涉及生成初始帧的数据,随后修改此数据以用于每个后续帧。

The approach of Using the FuncAnimation class is an efficient way to create animations by modifying the data of a plot for each frame. It allows us to create an animation by passing a user-defined function that iteratively modifies the data of a plot. This class involves generating data for the initial frame and subsequently modifying this data for each subsequent frame.

此示例演示了使用 FuncAnimation 类对正弦波绘图进行动画,演示对象的运动。它还使用 Matplotlib 动画更新 X 轴值。

This example demonstrates the use of FuncAnimation class to animate a sine wave plot, illustrating the motion of the object. And it is also updates the X-axis values using Matplotlib animation.

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()

以上示例生成以下输出 −

The above example produces the following output −

animations ex1

这里有另一个示例,它使用 FuncAnimation 类创建了一个动画的 3D 曲面图。

Here is another example that creates an animated 3D surface plot using FuncAnimation class.

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()

以上示例生成以下输出 −

The above example produces the following output −

animations ex5

ArtistAnimation

ArtistAnimation 是一种灵活的方法,适用于需要按顺序对不同的艺术家进行动画的场景。此方法涉及生成一个艺术家列表(可迭代),将它们绘制到动画的每帧中。

ArtistAnimation is a flexible approach suitable for scenarios where different artists need to be animated in a sequence. This approach involves generating a list (iterable) of artists to draw them into each frame of the animation.

此示例演示了使用 ArtistAnimation 类创建动画。

This example demonstrates the using of ArtistAnimation class to create the animation.

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()

上面的代码生成了以下结果 −

The above code generates the following results −

animations ex2

Saving animations

可以使用不同的多媒体编写器(如 Pillow、ffmpeg 和 imagemagick)将动画对象保存到磁盘。但是,需要注意的是,并非所有视频格式都受每个编写器支持。编写器主要有四种类型:

Saving animation objects to disk is possible using different multimedia writers, such as Pillow, ffmpeg, and imagemagick. However, it’s important to note that not all video formats are supported by every writer. There are four primary types of writers:

  1. PillowWriter

  2. HTMLWriter

  3. Pipe-based writers

  4. File-based writers

PillowWriter

它使用 Pillow 库以 GIF、APNG 和 WebP 等各种格式保存动画。

It uses the Pillow library to save animations in various formats, such as GIF, APNG, and WebP.

一个示例演示了对散点图进行动画并使用 PillowWriter 将其保存为 GIF。

An example demonstrates animating a scatterplot and saving that as a GIF using the PillowWriter.

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 文件 −

If you visit the folder where the output is saved you can observe below gif file −

animations ex3

HTMLWriter

HTMLWriter 用于创建基于 JavaScript 的动画,支持 HTML 和 PNG 格式。此编写器可用于将动画嵌入到网页中。

HTMLWriter is used for creating JavaScript-based animations, supporting HTML and PNG formats. This writer is useful for embedding animations in web pages.

Pipe-based writers

这些编写人员使用诸如 FFMpegWriter 和 ImageMagickWriter 之类的外部实用程序来创建动画。它们支持各种视频格式,并将帧传输到该实用程序,该实用程序将它们拼接在一起以创建动画。

These writers use external utilities like FFMpegWriter and ImageMagickWriter to create animations. They support various video formats and frames are piped to the utility, which stitches them together to create the animation.

File-based writers

基于文件的编写器(FFMpegFileWriter 和 ImageMagickFileWriter)稍慢,但提供在创建最终动画之前保存每个帧的优点。

File-based writers (FFMpegFileWriter and ImageMagickFileWriter) are slightly slower but offer the advantage of saving each frame before creating the final animation.

以下示例展示了如何正确为 matplotlib.animation 启用 ffmpeg 。在此,使用动画图像矩阵和动画彩色条创建绘图。

The following example shows how to properly enable ffmpeg for matplotlib.animation. Here the plot is created with an animated image matrix and the animated colorbar.

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)

执行上述代码时,您将获得以下输出 -

On executing the above code you will get the following output −

animations ex4