Python matplotlib如何使用blit和update更新文本?

3

我知道这个话题经常出现,但是经过多次尝试、搜索和放弃,我又把它带回来了。

我有一个类,其中包含一个matplotlib图形。在这个图形中,我想要一个文本,当用户按下某个键时,文本会更新为其他内容,而不必绘制轴中的所有繁重的东西。看起来我需要在这里使用blit,但是如何实现呢?这是一个可行的例子,是我目前为止能够做到的最好的。

import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np

class textUpdater:
    def __init__(self):
        self.fig, self.ax = plt.subplots()
        # self.text = plt.figtext(.02, .14, 'Blibli')
        self.text = self.ax.text(0, .5, 'Blabla')#, transform = self.ax.transAxes)#, animated=True)

        self.fig.canvas.mpl_connect('key_press_event', self.action)
        self.fig.canvas.draw()

        plt.show()

    def action(self, event):
        if event.key == 'z':
            self.text.set_text('Blooooo')
            self.ax.draw_artist(self.text)
            self.fig.canvas.blit(self.text.get_window_extent())

textUpdater()

第一个问题:当bliting物体时,以前的文本会出现在后面。我希望它消失!

第二个问题:事实上,我更喜欢将其作为fig文本,而不是任何轴线之外。这听起来可行吗?

你是最棒的,非常感谢。

1个回答

4
前面的文本仍然存在,因为您没有将其删除 - 您只是在其上绘制。为了防止这种情况发生,您应该保存文本所在的图形部分,然后显示文本,然后在文本更改时恢复保存的背景并重新显示文本。

matplotlib.ArtistAnimation已经为您完成了所有工作,因此您可以直接使用它:

import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib.animation import ArtistAnimation
import numpy as np

class textUpdater:
    def __init__(self):
        self.fig, self.ax = plt.subplots()
        self.text = self.ax.text(.5, .5, 'Blabla')

        self.fig.canvas.mpl_connect('key_press_event', self.action)
        self.fig.canvas.draw()

        self.animation = ArtistAnimation(self.fig, [(self.text,)])

        plt.show()

    def action(self, event):
        if event.key == 'z':
            self.text.set_text('Blooooo')

textUpdater()

现在,回答你的第二个问题,Figure.text 会创建一个属于该图形的文本,但是 ArtistAnimation 不支持不属于任何轴的艺术家,因此在这种情况下,您可能需要重新定义 ArtistAnimation 以支持此功能。


谢谢Tim!出于某种原因,我以为我必须远离mpl.animation,但是没错,那很完美。我会尝试将这个东西适应于Figure.text。再次感谢。 - Etienne
我已向Matplotlib提交了一个错误报告,关于不支持这种行为。我想很快就会提交一个补丁,但在那之前,您只需要重新定义ArtistAnimation._init_draw方法,使用artist.get_figure()代替artist.axes.figure即可。 - Tim Fuchs
@TimFuchs 你好!在更复杂的情况下,您是否只需将要动画化的所有艺术家放入“ArtistAnimation”构造函数中,然后像往常一样更新它们,而不必关心“ax.draw_artist(...)”或“figure.canvas.blit(ax.bbox)”?我正在遵循此解决方案,它可以工作,但是保存对艺术家的引用并在需要时恢复背景会产生很多开销。它仅适用于数据,而不适用于标题和标签... - Guimoute
@Guimoute 是的,我相信如此。ArtistAnimation应该为您处理所有的重绘和位块传输。 - Tim Fuchs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接