2012-05-03 17 views
8

Ho una griglia NxN con alcuni valori, che cambiano ogni volta che passo. Ho trovato un modo per tracciare una configurazione a griglia singola di questo con la funzione matshow, ma non so come aggiorno lo stato ad ogni passo temporale. Ecco un semplice esempio:
Modifica griglia quadratica animata (matshow)

from pylab import * 
from matplotlib import pyplot 

a = arange(25) 
a = a.reshape(5,5) 
b = 10*rand(5,5) 
matshow(a-b, cmap = cm.jet) 
colorbar() 
show() 

Questo codice produce il seguente quadro: enter image description here
Ora immaginate che il passo successivo tempo alcuni valori cambiano, in modo opportuno questa immagine. Questa è la logica che avevo in mente:

from pylab import * 
from matplotlib import pyplot 

a = arange(25) 
a = a.reshape(5,5) 
time=10 
for t in range(time): 
    b = 10*rand(5,5) 
    print b 
    matshow(a-b, cmap=cm.jet) 
    colorbar() 
show() 

Questo produce 10 immagini. Mi piacerebbe animare questo invece di produrre singole immagini, e per esempio mi piacerebbe scegliere un passaggio temporale tra le modifiche (cioè la frequenza dei fotogrammi).
Inoltre, sono aperto a suggerimenti per diverse funzioni, se matshow non è la strada da percorrere, ma per favore è semplice, sono relativamente inesperto.

risposta

13

matplotlib 1.1 dispone di un modulo di animazione (guarda il examples).

Usando animation.FuncAnimation è possibile aggiornare il plot in questo modo:

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

def generate_data(): 
    a = np.arange(25).reshape(5, 5) 
    b = 10 * np.random.rand(5, 5) 
    return a - b 

def update(data): 
    mat.set_data(data) 
    return mat 

def data_gen(): 
    while True: 
     yield generate_data() 

fig, ax = plt.subplots() 
mat = ax.matshow(generate_data()) 
plt.colorbar(mat) 
ani = animation.FuncAnimation(fig, update, data_gen, interval=500, 
           save_count=50) 
plt.show() 

È possibile salvare l'animazione utilizzando:

ani.save('animation.mp4') 

mi si salva con

ani.save('animation.mp4', clear_temp=False) 

le cornici sono conservato e puoi creare una gif animata come la seguente con

convert *.png animation.gif 

enter image description here

+0

Grazie, è quello che stavo cercando. – enedene

+1

Avrei dovuto chiedere questo nella domanda, ma c'è un modo per mettere una condizione su a-b in modo che l'animazione si fermi, e rimane solo l'ultima cifra (come se avessi tracciato una trama statica). Ad esempio se max (a-b)> 22? – enedene

+1

@bmu Mi sono preso la libertà di aggiungere alcuni fotogrammi del tuo "film" come una gif animata - ottima risposta! Guardando l'animazione, suggerirei che la barra di colore ha dei limiti fissi in modo che non cambi durante l'animazione. – Hooked

1

Il modo più semplice è probabilmente disporre di salvare le singole immagini in formato matplotlib e quindi aggiungere un altro programma o libreria a un'animazione. Questo approccio utilizza un modulo chiamato write2gif ma si può anche usare mencoder, ffmpeg o qualsiasi altro software in grado di produrre video:

from images2gif import writeGif 
from pylab import * 
from matplotlib import pyplot as plt 
from PIL import Image 

a = arange(25) 
a = a.reshape(5,5) 
time=10 
images = [] 
for t in range(time): 
    fig = plt.figure(figsize = (5, 5)) 
    ax = fig.add_subplot(111) 
    b = 10*rand(5,5) 
    cax = ax.matshow(a-b, cmap=cm.jet, vmin = -8, vmax = 24) 
    fname = 'tmp%03d.png' % t 
    fig.colorbar(cax) 
    fig.savefig(fname) 
    images.append(Image.open(fname)) 
writeGif('matanim.gif', images, duration = .2)  

Ecco un esempio su come farlo dal di dentro l'interfaccia di pylab. Non funziona così bene dal momento che la fusione continua viene eseguito nello stesso thread come pylabs gestori GUI:

from pylab import arange, cm, draw, rand 
from matplotlib import pylab as plt 
from time import sleep 
plt.ion() 
a = arange(25) 
a = a.reshape(5,5) 
fig = plt.figure(figsize = (5, 5)) 
for i in range(200): 
    ax = fig.add_subplot(111) 
    b = 10*rand(5,5) 
    cax = ax.matshow(a-b, cmap=cm.jet, vmin = -8, vmax = 24) 
    if i == 0: 
     fig.colorbar(cax) 
    draw() 
    sleep(0.2) 
+0

Grazie per la risposta. Esistono esempi di animazioni all'interno dell'interfaccia matplotlib, ad esempio: http://www.scipy.org/Cookbook/Matplotlib/Animations Non c'è modo per il mio esempio di essere animato anche all'interno di quell'interfaccia? – enedene

Problemi correlati