Animation using pcolormesh procedure in matplotlib, how can I initialize data?

I am trying to animate pcolormesh in matplotlib. I have seen many examples using package animations, most of which use a 1D plot program, and some of them with imshow (). Firstly, I decided to use the program FuncAnimation. My problem is that, firstly, I donโ€™t know if I can initialize the plot

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

I tried a few simple lines:

 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 ()

By the way, how to set tags and animations? Can I animate the title if it shows a number that changes over time? Thanks

+6
source share
4 answers

The problem was that I mistakenly used the set_array() procedure. It is very important to note that you must pass a 1D array to this routine. To do this, regarding this color, pcolormesh, etc. Usually builds multidimensional arrays, you should use .ravel (). Another important thing: in order to animate different graphs at the same time, the blitz option in animate.FuncAnimation must be False (see the "Animating Selected Story Elements" section of this link ).

Here I am posting the code for this simple program with various subtitles:

 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!!' 
+7
source

When using QuadMesh.set_array (), you need to guess the details that must be followed. If you intend to use QuadMesh with X, Y, and C, you can update the C values โ€‹โ€‹with set_array (). But set_array does not support the same input as the constructor. Reading the source shows that you need to pass a 1d array , and what is even more puzzling is that depending on the shading you might need to cut your C array .

Edit: There is even a very old error report about the confusing array size for shading='flat' .

It means:

Using QuadMesh.set_array () with shading = 'flat'

'flat' is the default value for 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() 

It looks like:

resulting graphic with shadig = flat

Note that if you omit C = C[:-1, :-1] , you will get this broken graphic:

broken graphic with shading = flat

Using QuadMesh.set_array () with 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() 

If you cut the last row / column with shade = 'gouraud', you will get:

 ValueError: total size of new array must be unchanged 
+5
source

I'm not sure why your quad = ax.pcolormesh (X, Y, Z) function gives an error. Can you post an error message?

Below I will do so to create a simple animation using 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() 

One of the frames: enter image description here

Does it help? If not, perhaps you can clarify this question.

+3
source

The following answer is presented here , which looks simpler the better (IMHO)

Here is a copy and paste of an alternative solution:

 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]) 
0
source

Source: https://habr.com/ru/post/953809/


All Articles