pyplot pcolormesh pcolor examples example color bar python animation matplotlib multidimensional-array

python - examples - Animación con la rutina pcolormesh en matplotlib, ¿cómo inicializo los datos?



pcolormesh example (4)

Intento animar una pcolormesh en matplotlib. He visto muchos ejemplos usando la animación del paquete, la mayoría de ellos usando una rutina de trazado 1D, y algunos de ellos con imshow (). Primero, quiero usar la rutina FuncAnimation. Mi problema es, primero, que no sé si puedo inicializar la trama

fig,ax = plt.subplots() quad = ax.pcolormesh(X,Y,Z)

He intentado algunas líneas simples:

fig,ax = plt.subplots() quad = ax.pcolormesh([]) def init(): quad.set_array([]) return quad, def animate(ktime): quad.set_array(X,Y,np.sin(Z)+ktime) return quad, anim = animation.FuncAnimation(fig,animate,init_func=init,frames=Ntime,interval=200,blit=True)

plt.show ()

Por cierto, ¿cómo configuro las etiquetas y la trama animada? ¿Puedo animar el título, si muestra un número que cambia en el tiempo? Gracias


No estoy seguro de por qué su función quad = ax.pcolormesh (X, Y, Z) está dando un error. ¿Puedes publicar el error?

A continuación se muestra lo que haría para crear una animación simple usando pcolormesh:

import matplotlib.pyplot as plt import numpy as np y, x = np.meshgrid(np.linspace(-3, 3,100), np.linspace(-3, 3,100)) z = np.sin(x**2+y**2) z = z[:-1, :-1] ax = plt.subplot(111) quad = plt.pcolormesh(x, y, z) plt.colorbar() plt.ion() plt.show() for phase in np.linspace(0,10*np.pi,200): z = np.sin(np.sqrt(x**2+y**2) + phase) z = z[:-1, :-1] quad.set_array(z.ravel()) plt.title(''Phase: %.2f''%phase) plt.draw() plt.ioff() plt.show()

Uno de los cuadros:

¿Esto ayuda? Si no, tal vez puedas aclarar la pregunta.


El problema era que estaba usando erróneamente la rutina set_array() . Es muy importante tener en cuenta que debe pasar una matriz 1D a esta rutina. Para hacerlo, con respecto a ese color, pcolormesh, etc. traza matrices multidimensionales, debe usar .ravel (). Una cosa más importante: para animar diferentes tramas al mismo tiempo, la opción blitz en animate.FuncAnimation debe ser False (Ver la sección "Animar los elementos seleccionados de la trama" de este enlace ).

Aquí publico el código de ese programa simple con varias subtramas:

import matplotlib.pyplot as plt import numpy as np import matplotlib.gridspec as gridspec import matplotlib.animation as animation y, x = np.meshgrid(np.linspace(-10, 10,100), np.linspace(-10, 10,100)) z = np.sin(x)*np.sin(x)+np.sin(y)*np.sin(y) v = np.linspace(-10, 10,100) t = np.sin(v)*np.sin(v) tt = np.cos(v)*np.cos(v) ########### fig = plt.figure(figsize=(16, 8),facecolor=''white'') gs = gridspec.GridSpec(5, 2) ax1 = plt.subplot(gs[0,0]) line, = ax1.plot([],[],''b-.'',linewidth=2) ax1.set_xlim(-10,10) ax1.set_ylim(0,1) ax1.set_xlabel(''time'') ax1.set_ylabel(''amplitude'') ax1.set_title(''Oscillationsssss'') time_text = ax1.text(0.02, 0.95, '''', transform=ax1.transAxes) ############################# ax2 = plt.subplot(gs[1:3,0]) quad1 = ax2.pcolormesh(x,y,z,shading=''gouraud'') ax2.set_xlabel(''time'') ax2.set_ylabel(''amplitude'') cb2 = fig.colorbar(quad1,ax=ax2) ######################### ax3 = plt.subplot(gs[3:,0]) quad2 = ax3.pcolormesh(x, y, z,shading=''gouraud'') ax3.set_xlabel(''time'') ax3.set_ylabel(''amplitude'') cb3 = fig.colorbar(quad2,ax=ax3) ############################ ax4 = plt.subplot(gs[:,1]) line2, = ax4.plot(v,tt,''b'',linewidth=2) ax4.set_xlim(-10,10) ax4.set_ylim(0,1) def init(): line.set_data([],[]) line2.set_data([],[]) quad1.set_array([]) return line,line2,quad1 def animate(iter): t = np.sin(2*v-iter/(2*np.pi))*np.sin(2*v-iter/(2*np.pi)) tt = np.cos(2*v-iter/(2*np.pi))*np.cos(2*v-iter/(2*np.pi)) z = np.sin(x-iter/(2*np.pi))*np.sin(x-iter/(2*np.pi))+np.sin(y)*np.sin(y) line.set_data(v,t) quad1.set_array(z.ravel()) line2.set_data(v,tt) return line,line2,quad1 gs.tight_layout(fig) anim = animation.FuncAnimation(fig,animate,frames=100,interval=50,blit=False,repeat=False) plt.show() print ''Finished!!''


Hay otra respuesta presentada aquí que parece más simple y mejor (en mi humilde opinión)

Aquí hay una copia y pega de la solución alternativa:

import matplotlib.pylab as plt from matplotlib import animation fig = plt.figure() plt.hold(True) #We need to prime the pump, so to speak and create a quadmesh for plt to work with plt.pcolormesh(X[0:1], Y[0:1], C[0:1]) anim = animation.FuncAnimation(fig, animate, frames = range(2,155), blit = False) plt.show() plt.hold(False) def animate( self, i): plt.title(''Ray: %.2f''%i) #This is where new data is inserted into the plot. plt.pcolormesh(X[i-2:i], Y[i-2:i], C[i-2:i])


Hay un detalle feo que debe tener cuidado al usar QuadMesh.set_array (). Si intactas tu QuadMesh con X, Y y C puedes actualizar los valores C usando set_array (). Pero set_array no admite la misma entrada que el constructor. La lectura de la fuente revela que debe pasar una matriz 1d y lo que es aún más desconcertante es que, dependiendo de la configuración de shading , es posible que necesite cortar la matriz C

Editar: Incluso hay un informe de error muy antiguo sobre el tamaño de matriz confuso para shading=''flat'' .

Eso significa:

Usando QuadMesh.set_array () con shading = ''flat''

''plano'' es el valor predeterminado para el shading .

# preperation import numpy as np import matplotlib.pyplot as plt plt.ion() y = np.linspace(-10, 10, num=1000) x = np.linspace(-10, 10, num=1000) X, Y = np.meshgrid(x, y) C = np.ones((1000, 1000)) * float(''nan'') # intantiate empty plot (values = nan) pcmesh = plt.pcolormesh(X, Y, C, vmin=-100, vmax=100, shading=''flat'') # generate some new data C = X * Y # necessary for shading=''flat'' C = C[:-1, :-1] # ravel() converts C to a 1d-array pcmesh.set_array(C.ravel()) # redraw to update plot with new data plt.draw()

Parece:

Tenga en cuenta que si omite C = C[:-1, :-1] obtendrá este gráfico roto:

Usando QuadMesh.set_array () con shading = ''gouraud''

# preperation (same as for ''flat'') import numpy as np import matplotlib.pyplot as plt plt.ion() y = np.linspace(-10, 10, num=1000) x = np.linspace(-10, 10, num=1000) X, Y = np.meshgrid(x, y) C = np.ones((1000, 1000)) * float(''nan'') # intantiate empty plot (values = nan) pcmesh = plt.pcolormesh(X, Y, C, vmin=-100, vmax=100, shading=''gouraud'') # generate some new data C = X * Y # here no cut of of last row/column! # ravel() converts C to a 1d-array pcmesh.set_array(C.ravel()) # redraw to update plot with new data plt.draw()

Si corta la última fila / columna con shade = ''gouraud'', obtendrá:

ValueError: total size of new array must be unchanged