Matplotlib is hiring a Research Software Engineering Fellow! See discourse for details. Apply by January 3, 2020

Version 3.1.1
matplotlib
Fork me on GitHub

目录

Related Topics

动画

动画

在Matplotlib中制作动态动画最简单的方法是使用 Animation 类。

FuncAnimation 通过重复调用函数制作动画 func .
ArtistAnimation 使用一组固定的动画 Artist 物体。

在这两种情况下,保持对实例对象的引用至关重要。动画是由计时器(通常来自主机GUI框架)进行的,该计时器 Animation 对象保存对的唯一引用。如果您不持有对 Animation 对象(以及计时器)将被垃圾收集,从而停止动画。

要将动画保存到磁盘,请使用 Animation.saveAnimation.to_html5_video

辅助类 下面是关于支持哪些电影格式的详细信息。

FuncAnimation

内部工作 FuncAnimation 或多或少是:

for d in frames:
   artists = func(d, *fargs)
   fig.canvas.draw_idle()
   fig.canvas.start_event_loop(interval)

通过细节处理“Blitting”(显著提高实时性能)、不阻塞、不重复启动/停止GUI事件循环、处理重复、多个动画轴,并轻松将动画保存到电影文件中。

“BLIT”是一个 old technique 在计算机图形学中。一般的要点是采取一个现有的位图(在我们的情况下,主要是栅格化的数字),然后'闪电'一个以上的艺术家。因此,通过管理保存的“干净”位图,我们只能重新绘制在每帧上都发生变化的少数艺术家,并可能节省大量时间。当我们使用Blitting(路过 blit=True )的核心循环 FuncAnimation 变得更加复杂:

ax = fig.gca()

def update_blit(artists):
    fig.canvas.restore_region(bg_cache)
    for a in artists:
        a.axes.draw_artist(a)

    ax.figure.canvas.blit(ax.bbox)

artists = init_func()

for a in artists:
   a.set_animated(True)

fig.canvas.draw()
bg_cache = fig.canvas.copy_from_bbox(ax.bbox)

for f in frames:
    artists = func(f, *fargs)
    update_blit(artists)
    fig.canvas.start_event_loop(interval)

当然,这会遗漏许多细节(例如,在调整图形大小或完全重新绘制图形时更新背景)。然而,这个可能是极简主义的例子给出了一个如何 init_funcfunc 在…内部使用 FuncAnimation 以及“闪电”如何工作的理论。

上的预期签名 funcinit_func 很容易保存 FuncAnimation 从你的簿记和绘图逻辑,但这意味着,你传递的可调用对象必须知道他们应该工作的艺术家。有几种方法可以处理这一问题,它们具有不同的复杂性和封装性。对于脚本来说,最简单的方法是在全局范围内定义艺术家,并让Python进行排序,这在脚本的情况下非常有效。例如::

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro')

def init():
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1, 1)
    return ln,

def update(frame):
    xdata.append(frame)
    ydata.append(np.sin(frame))
    ln.set_data(xdata, ydata)
    return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
                    init_func=init, blit=True)
plt.show()

第二种方法是 functools.partial 将艺术家“绑定”到功能。第三种方法是使用闭包来构建所需的艺术家和函数。第四种方法是创建类。

作家类

提供的作家可分为几个大类。

枕头作者依靠枕头库来编写动画,将所有数据保存在内存中。

PillowWriter

基于管道的编写器通过管道将捕获的帧流式传输到外部进程。基于管道的变体往往更具性能,但可能不适用于所有系统。

FFMpegWriter 基于管道的ffmpeg编写器。
ImageMagickWriter 基于管道的动画GIF。
AVConvWriter 基于管道的AVconv编写器。

基于文件的编写器为每个帧保存临时文件,这些帧在结尾处缝合成单个文件。虽然速度较慢,但这些编写器更容易调试。

FFMpegFileWriter 基于文件的ffmpeg编写器。
ImageMagickFileWriter 基于文件的动画gif书写器。
AVConvFileWriter 基于文件的avconv编写器。

基本上,A MovieWriter 提供从同一底层获取连续帧的方法 Figure 对象。基类 MovieWriter 实现3个方法和一个上下文管理器。基于管道和基于文件的编写器之间的唯一区别在于它们各自的参数 setup 方法。

这个 setup() 方法用于准备编写器(可能打开管道)、对 grab_frame() 一次捕获一帧,然后 finish() 完成电影并将输出文件写入磁盘。例如::

moviewriter = MovieWriter(...)
moviewriter.setup(fig=fig, 'my_movie.ext', dpi=100)
for j in range(n):
    update_figure(n)
    moviewriter.grab_frame()
moviewriter.finish()

如果直接使用writer类(而不是通过 Animation.save )强烈建议使用 saving 上下文管理器:

with moviewriter.saving(fig, 'myfile.mp4', dpi=100):
    for j in range(n):
        update_figure(n)
        moviewriter.grab_frame()

以确保根据需要执行设置和清理。

实例

辅助类

动画基础类

Animation 此类使用matplotlib包装动画的创建。
TimedAnimation Animation 基于时间的动画的子类。

作者注册

提供了一个模块级注册表,用于在编写器的名称和类之间进行映射,以允许将字符串传递给 Animation.save 而不是编写器实例。

MovieWriterRegistry 按人类可读的名称注册可用的编写器类。

编写器基类

减少代码重复的基类

AbstractMovieWriter 用于编写电影的抽象基类。
MovieWriter 用于编写电影的基类。
FileMovieWriter MovieWriter 用于写入单个文件并在末尾缝合。

和混音

AVConvBase 用于avconv输出的mixin类。
FFMpegBase 用于ffmpeg输出的mixin类。
ImageMagickBase ImageMagick输出的Mixin类。

提供。

有关如何轻松实现新的 MovieWriter 类。