matplotlib 动画:在没有第三方模块的情况下写入 png 文件

Arc*_*ast 4 python animation matplotlib

matplotlib 中的动画模块通常需要第三方模块,如 FFmpeg、mencoder 或 imagemagik 才能将动画保存到文件中(例如:https : //stackoverflow.com/a/25143651/5082048)。

甚至 matplotlib 中的 MovieWriter 类似乎也是以将第三方模块合并的方式构建的(启动和关闭进程,通过管道进行通信):http ://matplotlib.org/api/animation_api.html#matplotlib.animation.MovieWriter .

我正在寻找一种方法,如何将matplotlib.animation.FuncAnimation对象框架保存到框架到 png - 直接在 python 中。之后,我想使用这种方法在 iPython 笔记本中将 .png 文件显示为动画:https : //github.com/PBrockmann/ipython_animation_javascript_tool/

因此我的问题是:

  • 如何将matplotlib.animation.FuncAnimation对象直接保存到 .png 文件而无需使用第三方模块?
  • 是否有为此用例实现的编写器类?
  • 如何从 FuncAnimation 对象中逐帧获取图形对象(以便我可以自己保存它们)?

编辑:matplotlib.animation.FuncAnimation给出了对象,任务是使用纯 Python 保存它的帧。不幸的是,我无法像 ImportanceOfBeingErnest 建议的那样更改底层动画功能。

Imp*_*est 5

尽管这看起来有点复杂,但在动画本身中保存动画帧很容易。

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

def animate(i):
    line.set_ydata(np.sin(2*np.pi*i / 50)*np.sin(x))
    #fig.canvas.draw() not needed see comment by @tacaswell
    plt.savefig(str(i)+".png")
    return line,

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1,1)
x = np.linspace(0, 2*np.pi, 200)
line, = ax.plot(x, np.zeros_like(x))
plt.draw()

ani = matplotlib.animation.FuncAnimation(fig, animate, frames=5, repeat=False)
plt.show()
Run Code Online (Sandbox Code Playgroud)

注意这个repeat = False论点,这将阻止动画连续运行并重复将相同的文件写入磁盘。

请注意,如果您愿意放宽“无外部包”的限制,您可以使用 imagemagick 来保存 png

ani.save("anim.png", writer="imagemagick")
Run Code Online (Sandbox Code Playgroud)

这将保存文件 anim-1.png、anim-2.png 等。

最后请注意,当然还有更简单的方法可以在 jupyter notebook 中显示动画

  • @tacaswell 我不明白为什么这应该是一个坏主意。据我所知,这种方法没有任何问题,更重要的是,这是我目前看到的将动画保存到一堆 png 文件的唯一方法。非常欢迎您提供更好的方法,如果有的话。当然,将此方法记录在 matplotlib 文档中会更好。 (2认同)
  • @tacaswell 好点,我相应地编辑了答案。除此之外,我认为您对“直截了当”和“坏主意”的概念有点过分了。总之,让我只想说,在`ani.save(允许保存 png 的一些参数)` 意义上有一个有据可查的方法真的很有帮助。 (2认同)