2017-06-07 57 views
1

我有一个tkinter应用程序,可以绘制大量的数据,当我注意到画布上有大量数据时,平移和缩放性能不佳。Matplotlib tkagg后端性能

查看tkagg_backend(如this和其他几个问题所建议的),该函数和文档建议只有在用户闲置后才能重画画布。但是,从当前和以前的经验来看,画布一直在更新(重新绘制)中等缩放/平移。因此,我正在研究所涉及的具体功能并对此提出疑问。

的dynamic_update功能:

def dynamic_update(self): 
    'update drawing area only if idle' 
    # legacy method; new method is canvas.draw_idle 
    self.canvas.draw_idle() 

的canvas.draw_idle()函数:

def draw_idle(self): 
    'update drawing area only if idle' 
    if self._idle is False: 
     return 

    self._idle = False 

    def idle_draw(*args): 
     try: 
      self.draw() 
     finally: 
      self._idle = True 

    self._idle_callback = self._tkcanvas.after_idle(idle_draw) 

._idle参数被初始化为在后端True。这一点是我卡住的地方,因为我无法理解._idle如何链接到鼠标活动(我假设它是,请纠正我,如果这是错误的)。

有趣的是,画布的行为与我期望的self.canvas.draw_idle()行相同(一旦鼠标按钮未按下时重画),因此不会调用整个draw_idle函数。

因此,我的问题是如何设置_idle或为什么当我不是idle时,它会重新绘制整个画布?

回答

3

当提到“闲置”时,它不是用户或其鼠标活动的意思,而是GUI主循环。如果主循环当前不忙,画布应该重绘。在这里,当然self._idle只涉及GUI的matplotlib部分,以及draw_idle内部应该做的这个结构是为了防止画布在绘制时被绘制。

平移或缩放时很容易发生这种情况。鼠标移动到新的位置,导致重新绘制。在重绘正在进行的同时,鼠标已经进一步移动并导致下一次重绘。那时第一次重绘可能还没有完成,因此它会排队。等等,这样GUI在某些时候可能会变得没有反应。为了防止这种情况发生,只有在前一个完成后才会初始化一个新的抽奖,并且该行为由self._idle指引为真或假。