matplotlib 中的动画标题 [英] Animated title in matplotlib

查看:25
本文介绍了matplotlib 中的动画标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何在 FuncAnimation 绘图(使用 blit)上获得动画标题.基于 http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/Python/Matplotlib - 快速更新轴上的文本,我已经构建了一个动画,但文本部分不会动画.简化示例:

I can't figure out how to get an animated title working on a FuncAnimation plot (that uses blit). Based on http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/ and Python/Matplotlib - Quickly Updating Text on Axes, I've built an animation, but the text parts just won't animate. 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()

如果删除 blit=True,文本会显示出来,但速度会变慢.plt.titleax.set_titleax.text 似乎失败了.

If blit=True is removed, the text shows up, but it slows way down. It seems to fail with plt.title, ax.set_title, and ax.text.

我发现了为什么第一个链接中的第二个例子有效;文本位于 img 部分内.如果你把上面的 1.005 变成一个 .99,你就会明白我的意思.可能有一种方法可以用边界框来做到这一点,不知何故......

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

推荐答案

参见 动画 matplotlib 轴/刻度python matplotlib blit 到轴或边图?

所以,问题是在 animation 的内部实际上保存了 blit 背景(animation.py),它抓取边界框中的内容.当您有多个轴被独立设置动画时,这是有道理的.在您的情况下,您只有一个 axes 需要担心,我们希望为轴边界框的外部设置动画.通过一点猴子修补,对深入 mpl 的内脏和四处探索的容忍度,以及接受我们可以解决您的问题的最快和最脏的解决方案:

So, the problem is that in the guts of animation where the blit backgrounds are actually saved (line 792 of animation.py), it grabs what is in the axes bounding box. This makes sense when you have multiple axes being independently animated. In your case you only have one axes to worry about and we want to animate stuff outside of the axes bounding box. With a bit of monkey patching, a level of tolerance for reaching into the guts of mpl and poking around a bit, and acceptance of the quickest and dirtyest solution 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'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()

请注意,如果您的图形中有多个轴,这可能无法按预期工作.一个更好的解决方案是扩展 axes.bbox 只是 足以捕获您的标题 + 轴刻度标签.我怀疑 mpl 中的某个地方有代码可以做到这一点,但我不知道它在哪里.

Note that this may not work as expected if you have more than one axes in your figure. A much better solution is to expand the axes.bbox just enough to capture your title + axis tick labels. I suspect there is code someplace in mpl to do that, but I don't know where it is off the top of my head.

这篇关于matplotlib 中的动画标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆