1

我正在使用 matplotlib 计时器对象来注册我自己的动画更新函数。一旦回调开始,我似乎无法停止回调,但不保留对计时器对象的引用。

到目前为止,我的经验是,当我在 matplotlib 中创建一个对象时,我得到了对它的引用,但它也被添加到其他对象(图中的轴,轴中的线等)内的列表中,然后可以查询之后。但是,我找不到计时器对象的位置。我的问题可以用这个代码片段来概括

import matplotlib.pyplot as plt
import numpy as np

def update():
    plt.get_current_fig_manager().canvas.figure.patch.set_facecolor(str(np.random.random()))
    plt.draw()

def start_animation():
    timer = fig.canvas.new_timer(interval = 50)
    timer.add_callback(update)
    timer.start()

fig = plt.figure()
start_animation()

运行上面的代码片段,然后尝试以编程方式停止闪烁。需要调用的函数是

timer.remove_callback(update).  

要清楚。我知道我可以只保留对计时器对象的引用,这个问题就消失了。我正在寻找这个对象必须在 matplotlib 中的位置的解释。

4

1 回答 1

1

怎么样

 self.timer =  fig.canvas.new_timer(interval=100)
 ...
 self.timer.remove_callback(...)

澄清引用是在 callafter 方法中。您的图形或画布中没有存储参考,您可以在后端源代码中看到

def new_timer(self, *args, **kwargs):
    """
    Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
    This is useful for getting periodic events through the backend's native
    event loop. Implemented only for backends with GUIs.

    optional arguments:

    *interval*
      Timer interval in milliseconds
    *callbacks*
      Sequence of (func, args, kwargs) where func(*args, **kwargs) will
      be executed by the timer every *interval*.
    """
    return TimerTk(self._tkcanvas, *args, **kwargs)

它只是返回一个 TimerTK 实例。引用继续存在,因为在TimerTk.start()方法中您会看到一个 callafter 继续阻止计时器进行垃圾收集

 class TimerTK(TimerBase):
       ...
       def _timer_start(self):
           self._timer_stop()
           self._timer = self.parent.after(self._interval, self._on_timer)

这就是为什么每个示例都显示保存您自己对计时器的引用

于 2013-08-12T21:59:38.113 回答