2015-01-21 13 views
10

Voglio produrre un set di frame che può essere utilizzato per animare un grafico di una linea in crescita. In passato, ho sempre usato plt.draw() e set_ydata() per ridisegnare i dati y man mano che cambiava nel tempo. Questa volta, desidero disegnare una linea "crescente", spostandomi sul grafico nel tempo. Per questo motivo, set_ydata non funziona (xdata sta cambiando la lunghezza). Ad esempio,Animazione del grafico a linee "crescente" in Python/Matplotlib

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

plt.figure() 
for n in range(len(x)): 
    plt.plot(x[:n], y[:n], color='k') 
    plt.axis([0, 10, 0, 1]) 
    plt.savefig('Frame%03d.png' %n) 

Mentre questo funziona, diventa molto lento mentre si ridimensiona. C'è un modo più veloce per farlo?

+0

Avete un esempio (collegamento) a un grafico che ti piace che stai cercando di ricreare? Ci sono un sacco di pacchetti di animazione in Python che puoi usare. –

+0

@MylesBaker Ecco un esempio di come sarebbe (per il codice sopra): http://media.giphy.com/media/3xz2BD48KS3fOGzAJ2/giphy.gif – Blink

+0

Vuoi aggiornare i limiti del grafico man mano che più dati sono esposto? (Ie ridisegna il grafico)? O il tuo dominio e raggio sono conosciuti? –

risposta

19

Un paio di note:

Prima di tutto, la ragione per cui le cose diventano progressivamente più lenta è che si sta disegnando linee sempre più e più si sovrappongono nella stessa posizione.

Una soluzione rapida è quello di cancellare la trama ogni volta:

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

plt.figure() 
for n in range(len(x)): 
    plt.cla() 
    plt.plot(x[:n], y[:n], color='k') 
    plt.axis([0, 10, 0, 1]) 
    plt.savefig('Frame%03d.png' %n) 

Meglio ancora, però, aggiornare sia l'x ei dati y al tempo stesso:

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

fig, ax = plt.subplots() 
line, = ax.plot(x, y, color='k') 

for n in range(len(x)): 
    line.set_data(x[:n], y[:n]) 
    ax.axis([0, 10, 0, 1]) 
    fig.canvas.draw() 
    fig.savefig('Frame%03d.png' %n) 

E se si' Mi piace usare il modulo di animazione (nota a lato: blit=True potrebbe non funzionare correttamente su alcuni backend (es. OSX), quindi prova blit=False se hai problemi):

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 

x = np.linspace(0, 10, 100) 
y = np.sin(x) 

fig, ax = plt.subplots() 
line, = ax.plot(x, y, color='k') 

def update(num, x, y, line): 
    line.set_data(x[:num], y[:num]) 
    line.axes.axis([0, 10, 0, 1]) 
    return line, 

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y, line], 
           interval=25, blit=True) 
ani.save('test.gif') 
plt.show() 

enter image description here

+1

La soluzione 'set_data' è così elegante. Vorrei poter sopravvivere per 10 volte. –

Problemi correlati