Hen*_*ner 7 python animation matplotlib
我无法弄清楚如何在FuncAnimation图(使用blit)上获得动画标题.基于http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/和Python/Matplotlib - 快速更新Axes上的文本,我已经构建了一个动画,但文本部分刚赢了没有动画.简化示例:
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()
Run Code Online (Sandbox Code Playgroud)
如果blit=True
删除,文本会显示,但速度会慢下来.这似乎失败plt.title
,ax.set_title
和ax.text
.
编辑:我发现为什么第一个链接中的第二个例子有效; 文本在img
部分内部.如果你做上面的1.005
a .99
,你会明白我的意思.可能有一种方法可以使用边界框执行此操作,不知何故......
tac*_*ell 16
请参阅动画matplotlib轴/刻度和python matplotlib blit到图的轴或侧面?
因此,问题是在animation
实际保存blit背景的内容(animation.py的第792行)中,它抓住了轴边界框中的内容.当您有多个轴独立动画时,这是有意义的.在你的情况下你只需要axes
担心一个,我们想要在轴边界框之外设置动画.通过一些猴子修补,一定程度的容忍度,以达到mpl的内脏和一点点,并接受最快和最肮脏的解决方案,我们可以解决您的问题:
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's 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()
Run Code Online (Sandbox Code Playgroud)
请注意,如果图中有多个轴,则可能无法按预期工作.一个更好的解决办法是扩大axes.bbox
刚好足以捕捉你的标题+轴刻度标签.我怀疑在mpl中有代码可以做到这一点,但我不知道它在哪里.
要添加到tcaswell的"猴子修补"解决方案,以下是如何将动画添加到轴刻度标签.具体来说,要为x轴设置动画,请设置动画函数ax.xaxis.set_animated(True)
并ax.xaxis
从中返回.
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's 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()
Run Code Online (Sandbox Code Playgroud)