这些都是非常好的答案。这是另一个建议。@user621442 是正确的,瓶颈通常是图像的写入,因此如果您将 png 文件写入视频压缩器,它会非常慢(即使您通过管道发送它们而不是写入磁盘)。我找到了一个使用纯 ffmpeg 的解决方案,我个人觉得它比 matplotlib.animation 或 mencoder 更易于使用。
另外,就我而言,我只想将图像保存在轴中,而不是保存所有刻度标签、图形标题、图形背景等。基本上我想使用 matplotlib 代码制作电影/动画,但没有它“看起来像一个图表”。我已经在此处包含了该代码,但是如果您愿意,您可以制作标准图表并将它们通过管道传输到 ffmpeg。
import matplotlib.pyplot as plt
import subprocess
# create a figure window that is the exact size of the image
# 400x500 pixels in my case
# don't draw any axis stuff ... thanks to @Joe Kington for this trick
# https://stackoverflow.com/questions/14908576/how-to-remove-frame-from-matplotlib-pyplot-figure-vs-matplotlib-figure-frame
f = plt.figure(frameon=False, figsize=(4, 5), dpi=100)
canvas_width, canvas_height = f.canvas.get_width_height()
ax = f.add_axes([0, 0, 1, 1])
ax.axis('off')
def update(frame):
# your matplotlib code goes here
# Open an ffmpeg process
outf = 'ffmpeg.mp4'
cmdstring = ('ffmpeg',
'-y', '-r', '30', # overwrite, 30fps
'-s', '%dx%d' % (canvas_width, canvas_height), # size of image string
'-pix_fmt', 'argb', # format
'-f', 'rawvideo', '-i', '-', # tell ffmpeg to expect raw video from the pipe
'-vcodec', 'mpeg4', outf) # output encoding
p = subprocess.Popen(cmdstring, stdin=subprocess.PIPE)
# Draw 1000 frames and write to the pipe
for frame in range(1000):
# draw the frame
update(frame)
plt.draw()
# extract the image as an ARGB string
string = f.canvas.tostring_argb()
# write to pipe
p.stdin.write(string)
# Finish up
p.communicate()