2014-04-14 12 views
9

Ich versuche, die wigner Funktion der räumlichen Koordinaten einiger zeitabhängiger Daten zu animieren. Die wigner-Funktion ist zweidimensional, also verwende ich contourf(), um es zu plotten. Ich habe die Daten in einer HDF5-Datei gespeichert und kann Wigner-Distributionen im laufenden Betrieb erstellen, aber ich kann nicht herausfinden, wie man sie animiert. Alle Animationsanleitungen und Beispiele, die ich finden konnte (zum Beispiel this one und this one), sind ausschließlich für Liniendiagramme. Insbesondere verwendet ihre animate(i) Funktion line.set_data(), und ich kann nicht scheinen, ein Äquivalent für contourf() zu finden.Wie kann ich eine Animation mit contourf() machen?

Wie kann ich mit contourf() erstellte Bilder animieren?

Was ist das contourf() Äquivalent von set_data()?

+0

möglich Duplikat [Mit matplotlib.animate ein Konturdiagramm in Python animieren] (http://stackoverflow.com/questions/16915966/using-matplotlib-animate-to-animate-a-contour-plot -in-python) – Dan

+0

Was ich getan habe ist, jedes Mal ein neues Konturdiagramm zu erstellen und das alte zu verstecken, das ich 'cont.set_alpha (0)' mache. Hacky. Es sollte eine 'set_data' Methode geben. –

Antwort

3

Hier ist, was ich 2d Konturplots zu animieren verwenden, wurde es von http://matplotlib.org/examples/animation/dynamic_image2.html

import pylab as pl 
import numpy as np 
import matplotlib.animation as animation 
import types 


fig = pl.figure() 
# Some 2D arrays to plot (time,x,y) 
data = np.random.random_sample((20,10,10)) 

# ims is a list of lists, each row is a list of artists to draw in the 
# current frame; here we are just animating one artist, the image, in 
# each frame 
ims = [] 
for i in range(len(data[:,0,0])): 
    t_step = int(i) 
    im = pl.contourf(data[i,:,:]) 

    ################################################################# 
    ## Bug fix for Quad Contour set not having attribute 'set_visible' 
    def setvisible(self,vis): 
     for c in self.collections: c.set_visible(vis) 
    im.set_visible = types.MethodType(setvisible,im) 
    im.axes = pl.gca() 
    im.figure=fig 
    #################################################################### 

    ims.append([im]) 

ani = animation.ArtistAnimation(fig, ims, interval=70, blit=False,repeat_delay=1000) 

pl.show() 
1

angepasst Wenn Sie wie ich sind und die matplotlib.animation funktioniert nicht. Hier ist etwas anderes, was du ausprobieren kannst. Wenn Sie die Farbleiste und alle anderen Elemente in der Abbildung fortlaufend aktualisieren möchten, verwenden Sie plt.ion() ganz am Anfang, um das interaktive Plotten zu aktivieren, und verwenden Sie eine Kombination aus plt.draw() und plt.clf(), um die Zeichnung kontinuierlich zu aktualisieren . Es folgt ein Beispielcode:

import matplotlib.pyplot as plt 
import numpy as np 

plt.ion(); plt.figure(1); 
for k in range(10): 
    plt.clf(); plt.subplot(121); 
    plt.contourf(np.random.randn(10,10)); plt.colorbar(); 
    plt.subplot(122,polar=True) 
    plt.contourf(np.random.randn(10,10)); plt.colorbar(); 
    plt.draw(); 

Beachten Sie, dass dies funktioniert mit Zahlen verschiedenen Handlungsstränge und verschiedene Arten von Plots, die (das heißt polar oder kartesisch)

3

Ich Plotten geographische Daten und damit Basemap müssen. Basierend auf der Antwort von captain_M und Diskussion/Bug-Report auf https://github.com/matplotlib/matplotlib/issues/6139 ich eine Antwort hinterlassen, inspiriert von tacaswell, die Sie contourf in einer Animation von 2-dimensionalen Daten verwenden können und es als mp4 sparen, wenn Sie ffmpeg haben:

from matplotlib import animation 
from matplotlib import pyplot as plt 
import numpy as np 
from mpl_toolkits.basemap import Basemap 


fig, ax = plt.subplots() 

# set up map projection 
m = Basemap(projection='nsper',lon_0=-0,lat_0=90) 
m.drawcoastlines() 
m.drawparallels(np.arange(0.,180.,30.)) 
m.drawmeridians(np.arange(0.,360.,60.)) 

# some 2D geo arrays to plot (time,lat,lon) 
data = np.random.random_sample((20,90,360)) 
lat = np.arange(len(data[0,:,0])) 
lon = np.arange(len(data[0,0,:])) 
lons,lats = np.meshgrid(lon,lat) 

# ims is a list of lists, each row is a list of artists to draw in the 
# current frame; here we are animating three artists, the contour and 2 
# annotatons (title), in each frame 
ims = [] 
for i in range(len(data[:,0,0])): 
    im = m.contourf(lons,lats,data[i,:,:],latlon=True) 
    add_arts = im.collections 
    text = 'title={0!r}'.format(i) 
    te = ax.text(90, 90, text) 
    an = ax.annotate(text, xy=(0.45, 1.05), xycoords='axes fraction') 
    ims.append(add_arts + [te,an]) 

ani = animation.ArtistAnimation(fig, ims) 
## If you have ffmpeg you can save the animation by uncommenting 
## the following 2 lines 
# FFwriter = animation.FFMpegWriter() 
# ani.save('basic_animation.mp4', writer = FFwriter) 
plt.show() 
5

es gibt eine einfache Möglichkeit, es mit FuncAnimation zu tun: Sie müssen eine Funktion haben, die die Achse löscht und eine neue Kontur auf Rahmennummer basierend plotten. Vergessen Sie nicht blit als False einzustellen.

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

DATA = np.random.randn(800).reshape(10,10,8) 


fig,ax = plt.subplots() 

def animate(i): 
     ax.clear() 
     ax.contourf(DATA[:,:,i]) 
     ax.set_title('%03d'%(i)) 
     return ax 

interval = 2#in seconds  
ani = animation.FuncAnimation(fig,animate,5,interval=interval*1e+3,blit=False) 

plt.show()