2014-04-15 13 views
12

Sto tentando di salvare una semplice animazione matplotlib da Jake Vanderplas, ma continuo a ricevere OSError: [Errno 13] Permission denied.Impossibile salvare animazioni matplotlib con ffmpeg

Devo notare che ho apportato due piccole modifiche all'esempio di Jake Vanderplas. Ho installato ffmpeg da MacPorts, quindi ho aggiunto la riga plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin' e mi sono imbattuto nel problema discusso in (Using FFmpeg and IPython), quindi ho aggiunto FFwriter = animation.FFMpegWriter().

Ecco il codice:

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']) 

Ecco il traceback:

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 

Inoltre ho provato usando python built-in di Spyder e ha ricevuto un traceback simile. Eventuali suggerimenti?


MODIFICA: mi sono reso conto che non ho fornito il percorso corretto per ffmpeg. Apparentemente, plt.rcParams['animation.ffmpeg_path'] non funziona in modo simile a PYTHONPATH. Devi dire al modulo di animazione esattamente dove ffmpeg è con plt.rcParams['animation.ffmpeg_path'] = '/opt/local/bin/ffmpeg'.

Ora, ricevo un file filmato che verrà riprodotto, ma il contenuto è completamente confuso. Non posso dire quello che sto guardando.

Ecco il traceback:

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> 

EDIT: Per qualche motivo, tutto funziona bene ora. Ho provato cose sul mio computer di casa e sul mio computer di lavoro, e nessuno dei due può ricreare il file video confuso che ho ottenuto dopo aver risolto il problema del percorso ffmpeg.


EDIT: Aaaahaaa! Ho rintracciato questa ventosa. A volte vorrei importare un modulo che aveva plt.rcParams['savefig.bbox'] = 'tight' in esso. (Non userei mai quel modulo, ma rcParams persisterà, fino a quando non riavvierai il tuo interprete python.) Questa impostazione fa sì che il video esca completamente confuso. Pubblicherò la mia soluzione qui sotto.

+0

Aspettare .. ora si ottiene un traceback ma anche l'output? – KobeJohn

+0

Bene, crudele. Ho appena provato il mio codice sopra (con il percorso corretto per ffmpeg) sul mio computer di lavoro, e ha funzionato bene. Tutti i miei test prima di questo sono stati sul mio computer di casa. Forse ho bisogno di reinstallare ffmpeg sul mio computer di casa. – Stretch

risposta

15

Quindi risulta che c'erano due problemi.

Problema 1: il percorso per ffmpeg era errato. Pensavo di dover fornire il percorso alla directory in cui risiede ffmpeg, ma avevo bisogno di fornire il percorso fino al binario ffmpeg.

numero 2: prima di testare il mio codice per generare video, a volte avrei importato un modulo con l'impostazione plt.rcParams['savefig.bbox'] = 'tight'. (Non ci ho pensato molto, perché non ho usato il modulo, ma rcParams persistono finché non riavvii l'interprete python.) Questo plt.rcParams['savefig.bbox'] = 'tight' fa sì che il file video salvi senza errori, ma i frame sono tutti confusi quando provi a riprodurre il video. Anche se mi ci è voluto tutta la sera per rintracciare questo, si scopre che questo è a known issue.

Ecco la soluzione aggiornata che crea un file video per me con un'onda sinusoidale bella, traslante.

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() 
anim.save('basic_animation.mp4', writer = FFwriter, fps=30, extra_args=['-vcodec', 'libx264']) 
+0

Entrambi i problemi hanno risolto il mio problema in pochissimo tempo. Grazie! – Nigu

0

avevo garbling problemi quando ho (ingenuamente) provato a modificare il lavoro esempio di risposta 3 per mostrare il grafico in tempo reale (così come mantenere il film).

mods che non va di risposta 3 (che ha lavorato per me)

  1. plt.ion() # interazione
  2. plt.draw() e plt.show() all'interno la funzione animate , prima di ritorno statent
  3. fotogrammi = 20, intervallo = da 200 a rallentare grafico creazione un po ', ma ancora fare a 4 secondo film

Ora grafico mostra in una finestra mentre viene crea ted, ma il filmato di output è confuso.

corretto passaggio 2:

  • 2a: plt.draw() all'interno funzione animate
  • 2b: plt.show() subito dopo la funzione animate

Ora il film riproduce ungarbled.

+0

Ti riferisci alla risposta 3 sopra, ma il 3 è semplicemente il numero di "voti in su" per la mia risposta. Probabilmente è meglio fare riferimento alla mia risposta come "risposta di Stretch". – Stretch

Problemi correlati