Animated name in matplotlib

I can't figure out how to get an animated title running on the FuncAnimation plot (which uses blit). Based on http://jakevdp.imtqy.com/blog/2012/08/18/matplotlib-animation-tutorial/ and Python / Matplotlib - quick update of the text along the axes , I created an animation, but the text parts just do not expect. A simplified example:

import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np vls = np.linspace(0,2*2*np.pi,100) fig=plt.figure() img, = plt.plot(np.sin(vls)) ax = plt.axes() ax.set_xlim([0,2*2*np.pi]) #ttl = ax.set_title('',animated=True) ttl = ax.text(.5, 1.005, '', transform = ax.transAxes) def init(): ttl.set_text('') img.set_data([0],[0]) return img, ttl def func(n): ttl.set_text(str(n)) img.set_data(vls,np.sin(vls+.02*n*2*np.pi)) return img, ttl ani = animation.FuncAnimation(fig,func,init_func=init,frames=50,interval=30,blit=True) plt.show() 

If blit=True is deleted, the text appears, but it slows down. It seems to fail with plt.title , ax.set_title and ax.text .

Edit: I found out why the second example worked in the first link; the text was inside the img part. If you do above 1.005 a .99 , you will see what I mean. There is probably a way to do this with a bounding box, somehow ...

+6
source share
4 answers

See animating matplotlib axes / ticks and python matplotlib blit for axes or sides of a shape?

So the problem is that in the guts of the animation , where blit backgrounds are actually stored (line 792 animation.py ), it captures what's in the bounding box of the axes. This makes sense when you have several axes that are independently animated. In your case, you only have one axes to worry about, and we want to animate the material outside the bounding box of the axes. With a small number of monkey fixes, a level of tolerance for achieving mpl courage and a little gouging, and making the quickest and most dirty decision, we can solve your problem as such:

 import matplotlib import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np def _blit_draw(self, artists, bg_cache): # Handles blitted drawing, which renders only the artists given instead # of the entire figure. updated_ax = [] for a in artists: # If we haven't cached the background for this axes object, do # so now. This might not always be reliable, but it an attempt # to automate the process. if a.axes not in bg_cache: # bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox) # change here bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.figure.bbox) a.axes.draw_artist(a) updated_ax.append(a.axes) # After rendering all the needed artists, blit each axes individually. for ax in set(updated_ax): # and here # ax.figure.canvas.blit(ax.bbox) ax.figure.canvas.blit(ax.figure.bbox) # MONKEY PATCH!! matplotlib.animation.Animation._blit_draw = _blit_draw vls = np.linspace(0,2*2*np.pi,100) fig=plt.figure() img, = plt.plot(np.sin(vls)) ax = plt.axes() ax.set_xlim([0,2*2*np.pi]) #ttl = ax.set_title('',animated=True) ttl = ax.text(.5, 1.05, '', transform = ax.transAxes, va='center') def init(): ttl.set_text('') img.set_data([0],[0]) return img, ttl def func(n): ttl.set_text(str(n)) img.set_data(vls,np.sin(vls+.02*n*2*np.pi)) return img, ttl ani = animation.FuncAnimation(fig,func,init_func=init,frames=50,interval=30,blit=True) plt.show() 

Note that this may not work as expected if your figure has several axes. A much better solution is to extend axes.bbox to capture header + axis labels. I suspect there is code somewhere in mpl, but I don't know where it is on my head.

+14
source

To add “monkey fix” to tcaswell, here's how you can add animation to axis label labels. In particular, to animate the x axis, set ax.xaxis.set_animated(True) and return ax.xaxis from the animation functions.

 import matplotlib import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np def _blit_draw(self, artists, bg_cache): # Handles blitted drawing, which renders only the artists given instead # of the entire figure. updated_ax = [] for a in artists: # If we haven't cached the background for this axes object, do # so now. This might not always be reliable, but it an attempt # to automate the process. if a.axes not in bg_cache: # bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox) # change here bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.figure.bbox) a.axes.draw_artist(a) updated_ax.append(a.axes) # After rendering all the needed artists, blit each axes individually. for ax in set(updated_ax): # and here # ax.figure.canvas.blit(ax.bbox) ax.figure.canvas.blit(ax.figure.bbox) # MONKEY PATCH!! matplotlib.animation.Animation._blit_draw = _blit_draw vls = np.linspace(0,2*2*np.pi,100) fig=plt.figure() img, = plt.plot(np.sin(vls)) ax = plt.axes() ax.set_xlim([0,2*2*np.pi]) #ttl = ax.set_title('',animated=True) ttl = ax.text(.5, 1.05, '', transform = ax.transAxes, va='center') ax.xaxis.set_animated(True) def init(): ttl.set_text('') img.set_data([0],[0]) return img, ttl, ax.xaxis def func(n): ttl.set_text(str(n)) vls = np.linspace(0.2*n,0.2*n+2*2*np.pi,100) img.set_data(vls,np.sin(vls)) ax.set_xlim(vls[0],vls[-1]) return img, ttl, ax.xaxis ani = animation.FuncAnimation(fig,func,init_func=init,frames=60,interval=200,blit=True) plt.show() 
+2
source

You have to call

 plt.draw() 

After

 ttl.set_text(str(n)) 

Here is a very simple example of text animation inside a "no FuncAnimation ()" shape. Try it, you will see if it is useful to you.

 import matplotlib.pyplot as plt import numpy as np titles = np.arange(100) plt.ion() fig = plt.figure() for text in titles: plt.clf() fig.text(0.5,0.5,str(text)) plt.draw() 
+1
source

If you need to fix the title, you can simply update the title:

 fig.suptitle() 

See the drawing API document .

+1
source

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


All Articles