2013-08-20 26 views
15

Ho un grafico a dispersione impostato e tracciato nel modo in cui lo voglio, e voglio creare un video .mp4 della figura ruotando nello spazio, come se avessi usato plt.show() e trascinato il punto di vista intorno.Animare un grafico 3D rotante in matplotlib

This answer è quasi esattamente quello che voglio, tranne che per salvare un film dovrei chiamare manualmente in FFMpeg con una cartella di immagini. Invece di salvare singoli frame, preferirei usare il supporto per animazioni integrato di Matplotlib. Codice di seguito riprodotto:

from mpl_toolkits.mplot3d import Axes3D 
ax = Axes3D(fig) 
ax.scatter(xx,yy,zz, marker='o', s=20, c="goldenrod", alpha=0.6) 
for ii in xrange(0,360,1): 
    ax.view_init(elev=10., azim=ii) 
    savefig("movie"%ii+".png") 
+0

Ha funzionato perfettamente, grazie! – Nate

risposta

20

Se volete saperne di più su matplotlib animazioni si dovrebbe davvero seguire this tutorial. Spiega in modo dettagliato come creare grafici animati.

Nota: La creazione di grafici animati richiede ffmpeg o mencoder da installare.

Ecco una versione del suo primo esempio modificata per funzionare con il grafico a dispersione.

# First import everthing you need 
import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib import animation 
from mpl_toolkits.mplot3d import Axes3D 

# Create some random data, I took this piece from here: 
# http://matplotlib.org/mpl_examples/mplot3d/scatter3d_demo.py 
def randrange(n, vmin, vmax): 
    return (vmax - vmin) * np.random.rand(n) + vmin 
n = 100 
xx = randrange(n, 23, 32) 
yy = randrange(n, 0, 100) 
zz = randrange(n, -50, -25) 

# Create a figure and a 3D Axes 
fig = plt.figure() 
ax = Axes3D(fig) 

# Create an init function and the animate functions. 
# Both are explained in the tutorial. Since we are changing 
# the the elevation and azimuth and no objects are really 
# changed on the plot we don't have to return anything from 
# the init and animate function. (return value is explained 
# in the tutorial. 
def init(): 
    ax.scatter(xx, yy, zz, marker='o', s=20, c="goldenrod", alpha=0.6) 
    return fig, 

def animate(i): 
    ax.view_init(elev=10., azim=i) 
    return fig, 

# Animate 
anim = animation.FuncAnimation(fig, animate, init_func=init, 
           frames=360, interval=20, blit=True) 
# Save 
anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264']) 
+1

Scusa, spero che tu non sia effettivamente offeso. Non sono sicuro di essere d'accordo con te sulla mancanza di valori di ritorno. Penso che 'blit' abbia bisogno che funzionino correttamente, ma quella sezione della libreria è ancora un po 'una scatola nera per me. (Ho votato in su la risposta). – tacaswell

+1

Certo che no! : D Rispetto davvero molto i tuoi commenti, poiché provengono da uno sviluppatore esperto di 'matplotlib'! E cerco di imparare da loro e di comportarmi secondo i tuoi suggerimenti (ieri sulla segnalazione flag). Quindi, per favore ** DO ** correggimi ogni volta che pensi che ho fatto qualcosa di sbagliato :). È nell'interesse della comunità SO e del mio processo di apprendimento. E 'successo che abbiamo avuto un leggero disaccordo metodologico sulla domanda precedente quindi ho aggiunto questo come uno scherzo dato che sapevo che avresti letto tutte le domande 'matplotlib' :) –

+0

Informazioni sul valore di ritorno. Nel post del blog, Jake ha dichiarato: "È importante che questa funzione restituisca l'oggetto linea, perché questo comunica all'animatore quali oggetti del grafico aggiornare dopo ogni fotogramma". Ma dal momento che nessuno degli oggetti sulla trama cambia, ho pensato che nulla dovesse essere restituito. Modificheremo il post se questa è un'ipotesi errata. –

Problemi correlati