无法使用 ffmpeg 保存 matplotlib 动画 [英] Cannot save matplotlib animation with ffmpeg

查看:32
本文介绍了无法使用 ffmpeg 保存 matplotlib 动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 Jake 保存一个简单的 matplotlib 动画Vanderplas,但我不断收到 OSError: [Errno 13] Permission denied.

I am trying to save a simple matplotlib animation from Jake Vanderplas, but I keep getting OSError: [Errno 13] Permission denied.

我应该注意到,我对 Jake Vanderplas 的例子做了两个小的修改.我从 MacPorts 安装了 ffmpeg,所以我添加了行 plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin' 并且我遇到了 (使用FFmpeg和IPython),所以我添加了FFwriter = animation.FFMpegWriter()代码>.

I should note that I made two small modifications to Jake Vanderplas's example. I installed ffmpeg from MacPorts so I added the line plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin' and I ran into the problem discussed in (Using FFmpeg and IPython), so I added FFwriter = animation.FFMpegWriter().

代码如下:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin'

fig = plt.figure()
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
line, = ax.plot([], [], lw=2)

def init():
    line.set_data([], [])
    return line,

def animate(i):
    x = np.linspace(0, 2, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,
                           frames=200, interval=20, blit=True)

FFwriter = animation.FFMpegWriter()
anim.save('basic_animation.mp4', writer = FFwriter, fps=30, extra_args=['-vcodec', 'libx264'])

这是回溯:

File "ani_debug.py", line 34, in <module>
  anim.save('basic_animation.mp4', writer = FFwriter, fps=30, extra_args=['-vcodec', 'libx264'])
File "/Users/Ben/Library/Enthought/Canopy_64bit/User/lib/python2.7/site- packages/matplotlib/animation.py", line 712, in save
  with writer.saving(self._fig, filename, dpi):
File "/Applications/Canopy.app/appdata/canopy-1.3.0.1715.macosx-x86_64/Canopy.app/Contents/lib/python2.7/contextlib.py", line 17, in __enter__
  return self.gen.next()
File "/Users/Ben/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/matplotlib/animation.py", line 169, in saving
  self.setup(*args)
File "/Users/Ben/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/matplotlib/animation.py", line 159, in setup
  self._run()
File "/Users/Ben/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/matplotlib/animation.py", line 186, in _run
  stdin=subprocess.PIPE)
File "/Applications/Canopy.app/appdata/canopy-1.3.0.1715.macosx-x86_64/Canopy.app/Contents/lib/python2.7/subprocess.py", line 709, in __init__
  errread, errwrite)
File "/Applications/Canopy.app/appdata/canopy-1.3.0.1715.macosx-x86_64/Canopy.app/Contents/lib/python2.7/subprocess.py", line 1326, in _execute_child
  raise child_exception
OSError: [Errno 13] Permission denied

我也尝试过使用 Spyder 的内置 python 并收到类似的回溯.有什么建议吗?

I have also tried using Spyder's built-in python and received a similar traceback. Any suggestions?

我意识到我没有给出 ffmpeg 的正确路径.显然,plt.rcParams['animation.ffmpeg_path'] 不像 PYTHONPATH 那样工作.您必须使用 plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin/ffmpeg' 告诉动画模块 ffmpeg 的确切位置.

I realized that I did not give the proper path to ffmpeg. Apparently, plt.rcParams['animation.ffmpeg_path'] does not work similar to PYTHONPATH. You must tell the animation module exactly where ffmpeg is with plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin/ffmpeg'.

现在,我得到一个可以播放的电影文件,但内容完全是乱码.我不知道我在看什么.

Now, I get a movie file that will play, but the content is completely garbled. I can't tell what I am looking at.

这是回溯:

Exception in Tkinter callback
Traceback (most recent call last):
  File "Tkinter.pyc", line 1470, in __call__
  File "Tkinter.pyc", line 531, in callit
  File "/Applications/Spyder.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_tkagg.py", line 141, in _on_timer
    TimerBase._on_timer(self)
  File "/Applications/Spyder.app/Contents/Resources/lib/python2.7/matplotlib/backend_bases.py", line 1203, in _on_timer
    ret = func(*args, **kwargs)
  File "/Applications/Spyder.app/Contents/Resources/lib/python2.7/matplotlib/animation.py", line 876, in _step
    still_going = Animation._step(self, *args)
  File "/Applications/Spyder.app/Contents/Resources/lib/python2.7/matplotlib/animation.py", line 735, in _step
    self._draw_next_frame(framedata, self._blit)
  File "/Applications/Spyder.app/Contents/Resources/lib/python2.7/matplotlib/animation.py", line 753, in _draw_next_frame
    self._pre_draw(framedata, blit)
  File "/Applications/Spyder.app/Contents/Resources/lib/python2.7/matplotlib/animation.py", line 766, in _pre_draw
    self._blit_clear(self._drawn_artists, self._blit_cache)
  File "/Applications/Spyder.app/Contents/Resources/lib/python2.7/matplotlib/animation.py", line 806, in _blit_clear
    a.figure.canvas.restore_region(bg_cache[a])
KeyError: <matplotlib.axes.AxesSubplot object at 0x104cfb150>

<小时>

出于某种原因,现在一切正常.我在家用电脑和工作电脑上都试过了,修复ffmpeg路径问题后得到的视频文件乱码都没有.


For some reason, everything is working fine now. I have tried things on my home computer and my work computer, and neither one can recreate the garbled video file I got after I fixed the ffmpeg path issue.

啊啊啊!我追踪到了这个傻瓜.有时我会导入一个包含 plt.rcParams['savefig.bbox'] = 'tight' 的模块.(我永远不会使用该模块,但 rcParams 会一直存在,直到您重新启动 Python 解释器.)该设置会导致视频出现乱码.我将在下面发布我的解决方案.

Aaaahaaa! I tracked this sucker down. Sometimes I would import a module that had plt.rcParams['savefig.bbox'] = 'tight' in it. (I would never use that module, but rcParams persist, until you restart your python interpreter.) That setting causes the video to come out all garbled. I will post my solution below.

推荐答案

原来有两个问题.

问题#1:ffmpeg 的路径是错误的.我以为我需要提供 ffmpeg 所在目录的路径,但我需要提供一直到 ffmpeg 二进制文件的路径.

Issue #1: The path to ffmpeg was wrong. I thought I needed to provide the path to the directory that ffmpeg resides in, but I needed to provide the path all the way to the ffmpeg binary.

问题 #2:在测试我的代码以生成视频之前,我有时会导入一个设置为 plt.rcParams['savefig.bbox'] = 'tight' 的模块.(我没有多想,因为我没有使用该模块,但是 rcParams 会一直存在,直到您重新启动 python 解释器.)这个 plt.rcParams['savefig.bbox'] = 'tight'导致视频文件保存没有任何错误,但是当您尝试播放视频时,帧都是乱码.虽然我花了整晚才找到这个问题,但事实证明这是一个已知问题.

Issue #2: Prior to testing out my code to generate videos, I sometimes would import a module with the setting plt.rcParams['savefig.bbox'] = 'tight'. (I did not think much of it, because I did not use the module, but rcParams persist until you restart the python interpreter.) This plt.rcParams['savefig.bbox'] = 'tight' causes the video file to save without any errors, but the frames are all garbled when you try to play the video. Although it took me all evening to track this down, it turns out this is a known issue.

这是更新的解决方案,它为我创建了一个带有漂亮的平移正弦波的视频文件.

Here is the updated solution that creates a video file for me with a nice, translating, sine wave.

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin/ffmpeg'

fig = plt.figure()
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
line, = ax.plot([], [], lw=2)

def init():
    line.set_data([], [])
    return line,

def animate(i):
    x = np.linspace(0, 2, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=True)

FFwriter = animation.FFMpegWriter(fps=30, extra_args=['-vcodec', 'libx264'])
anim.save('basic_animation.mp4', writer=FFwriter)

这篇关于无法使用 ffmpeg 保存 matplotlib 动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆