matplotlib中的动画模块通常需要第三方模块,如FFmpeg,mencoder或imagemagik才能将动画保存到文件中(例如:https://stackoverflow.com/a/25143651/5082048)。
即使是matplotlib中的MovieWriter类似乎也是以第三方模块的合并方式构建的(开始和结束过程,通过管道进行通信):http://matplotlib.org/api/animation_api.html#matplotlib.animation.MovieWriter。
我正在寻找一种方法,如何在python中直接将matplotlib.animation.FuncAnimation
对象框架保存到框架到png。之后,我想使用这种方法在iPython笔记本中将.png文件显示为动画:https://github.com/PBrockmann/ipython_animation_javascript_tool/
因此我的问题是:
matplotlib.animation.FuncAnimation
对象直接保存到.png文件而无需使用第三方模块? 编辑:给出matplotlib.animation.FuncAnimation
对象,任务是使用纯Python保存它的帧。不幸的是,我无法像ImportanceOfBeingErnest建议的那样更改底层动画功能。
答案 0 :(得分:3)
虽然这看起来有点复杂,但在动画中可以很容易地保存动画帧。
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()
注意repeat = False
参数,这将阻止动画连续运行并重复将相同的文件写入磁盘。
请注意,如果您愿意放宽"没有外部包裹的限制"你可以使用imagemagick来保存pngs
ani.save("anim.png", writer="imagemagick")
将保存文件anim-1.png,anim-2.png等。
最后请注意,当然有easier methods to show an animation in a jupyter notebook。
答案 1 :(得分:2)
您想查看FileMovieWriter
子类(请参阅http://matplotlib.org/2.0.0rc2/api/animation_api.html#writer-classes)您可能希望子类FileMoveWriter
,例如
import matplotlib.animation as ma
class BunchOFiles(ma.FileMovieWriter):
def setup(self, fig, dpi, frame_prefix):
super().setup(fig, dpi, frame_prefix, clear_temp=False)
def _run(self):
# Uses subprocess to call the program for assembling frames into a
# movie file. *args* returns the sequence of command line arguments
# from a few configuration options.
pass
def grab_frame(self, **savefig_kwargs):
'''
Grab the image information from the figure and save as a movie frame.
All keyword arguments in savefig_kwargs are passed on to the 'savefig'
command that saves the figure.
'''
# Tell the figure to save its data to the sink, using the
# frame format and dpi.
with self._frame_sink() as myframesink:
self.fig.savefig(myframesink, format=self.frame_format,
dpi=self.dpi, **savefig_kwargs)
def cleanup(self):
# explictily skip a step in the mro
ma.MovieWriter.cleanup(self)
(未经过测试,最好只实现一个实现saving
,grab_frame
,finished
和setup
)的类
答案 2 :(得分:2)
未经修改,我无法获得塔卡斯韦尔的答案。所以,这就是我的看法。
from matplotlib.animation import FileMovieWriter
class BunchOFiles(FileMovieWriter):
supported_formats = ['png', 'jpeg', 'bmp', 'svg', 'pdf']
def __init__(self, *args, extra_args=None, **kwargs):
# extra_args aren't used but we need to stop None from being passed
super().__init__(*args, extra_args=(), **kwargs)
def setup(self, fig, dpi, frame_prefix):
super().setup(fig, dpi, frame_prefix, clear_temp=False)
self.fname_format_str = '%s%%d.%s'
self.temp_prefix, self.frame_format = self.outfile.split('.')
def grab_frame(self, **savefig_kwargs):
'''
Grab the image information from the figure and save as a movie frame.
All keyword arguments in savefig_kwargs are passed on to the 'savefig'
command that saves the figure.
'''
# Tell the figure to save its data to the sink, using the
# frame format and dpi.
with self._frame_sink() as myframesink:
self.fig.savefig(myframesink, format=self.frame_format,
dpi=self.dpi, **savefig_kwargs)
def finish(self):
self._frame_sink().close()
我们可以使用以下方法保存一组文件:
anim.save('filename.format', writer=BunchOFiles())
,它将以'filename {number} .format'的形式保存文件。