首页 > 解决方案 > How can I check if the event queue is finished for the on_pick event of matplotlib?

问题描述

I plotted a graph with matplotlib, and I want to interact with it when I clicked some of the points. I have many points overlapping on each other.

def foo():
    plist = list()
    data = data_generator()
    for ind in range(0, len(data)):
        x_plot, y_plot = generator()
        paths = ax.plot(x_plot, y_plot, alpha=alpha)
        plist.append(paths[0])

class AbstractPlotPage(tk.Frame):
    def __init__():
        self.paths = foo()
        self.canvas = FigureCanvasTkAgg(f, self)
        self.canvas.mpl_connect('pick_event', self.on_pick)
        self.canvas.show()
    def on_pick():
        print('test')

The thing is, I noticed matplotlib does not run the on_pick once for all the overlapped points. But it runs once for a single points then run it again.

So is there a way to check when the event queue is done? Or how can I watch this event queue?

标签: pythonmatplotlib

解决方案


如果有人感兴趣,我找到了一些解释,但不是真正的解决方案。以下是艺术家的代码,每次调用 self.figure.canvas.pick_event 时,事件都会运行回调。基本上,这个递归迭代了一个图形上的所有元素,所以如果你选择了多个点,回调将运行多次。

如何处理?我想你应该从 matplotlib 重新编写一些代码。我认为我的版本有点太旧了,它是 1. 的东西。也许较新的版本已经做了一些改变。

def pick(self, mouseevent):
    """
    call signature::

      pick(mouseevent)

    each child artist will fire a pick event if *mouseevent* is over
    the artist and the artist has picker set
    """
    # Pick self
    if self.pickable():
        picker = self.get_picker()
        if six.callable(picker):
            inside, prop = picker(self, mouseevent)
        else:
            inside, prop = self.contains(mouseevent)
        if inside:
            self.figure.canvas.pick_event(mouseevent, self, **prop)

    # Pick children
    for a in self.get_children():
        # make sure the event happened in the same axes
        ax = getattr(a, 'axes', None)
        if mouseevent.inaxes is None or ax is None or \
                mouseevent.inaxes == ax:
            # we need to check if mouseevent.inaxes is None
            # because some objects associated with an axes (e.g., a
            # tick label) can be outside the bounding box of the
            # axes and inaxes will be None
            # also check that ax is None so that it traverse objects
            # which do no have an axes property but children might
            a.pick(mouseevent)

推荐阅读