如何在同一个图上处理侦听motion_notify_event的多个对象

时间:2013-11-19 19:12:59

标签: python matplotlib event-handling

我正在使用matplotlib:

假设我有一个对象A,它有两个属性B和C,以及一个绘制图形的方法。 B和C都有方法在事件'motion_notify_event'上的图上做一些事情。

我注意到这两种方法不能同时工作,似乎存在冲突。

如何处理此类案件?

所以我写了一个代码,比上面的解释更好一点。

import matplotlib.pyplot as plt
from matplotlib.widgets import MultiCursor
from matplotlib.patches import Circle


class Event1(object):

    def __init__(self,axes):

        self.fig  = axes[0].figure
        self.axes = axes

        self.eid = self.fig.canvas.mpl_connect('motion_notify_event',self.onmove)


    def onmove(self,event):
        for ax in self.axes:
            c = Circle((event.xdata,event.ydata),radius=0.05)
            ax.add_patch(c)
            ax.draw_artist(c)

        self.fig.canvas.blit(self.fig.bbox)



class plotclass(object):

    def __init__(self):

        pass

    def plotme(self):

        self.fig = plt.figure()
        self.ax1 = self.fig.add_subplot(211)
        self.ax2 = self.fig.add_subplot(212)

        for ax in (self.ax1,self.ax2):
            ax.set_xlim((0,10))
            ax.set_ylim((0,10))

#       self.curs = MultiCursor(self.fig.canvas,(self.ax1,self.ax2))

        self.ev1 = Event1((self.ax1,self.ax2))

        self.fig.show()



def main():

    pc = plotclass()

    return pc


if __name__ == '__main__':
    main()

现在在这段代码中有两个东西正在监听motion_notify_event:类Event1,它将在光标位置绘制圆圈,以及类'plotclass',它创建图形并在光标位置绘制光标。

我已经注释掉了self.curs = ...这一行,当鼠标移动时我看到了圆圈,但如果我取消注释它,我只看到游标:为什么?以及如何看待它们?

1 个答案:

答案 0 :(得分:1)

只是详细说明我上面的评论,这不是由于多事件处理,而是由于blitting的不同阶段相互覆盖。

Blitting通常通过恢复已保存的完全渲染状态然后在其上绘制来工作。

在你当前的代码中,你是blitting但没有恢复已保存的状态,所以你得到一个圆圈的“踪迹”(大概这就是你想要的)。

但是,MultiCursor在绘制之前调用fig.canvas.restore_region(...) (否则你会有一条“线”)。因此,它会恢复一个已保存的“空白”数字,而不是刚刚绘制的内容。

如果你想使用多次布局,他们需要相互协调。有许多不同的方法可以解决这个问题,但对于大多数用例来说,这些方法都有些过分。快速解决方法是将useblit=False传递给MultiCursor。但是,这会降低渲染速度。

你能详细说明你想做什么吗?你只想要一个带有圆圈的光标在鼠标位置吗? (如果是这样,只是子类MultiCursor。)