Matplotlib pick event order for overlapping artists
Posted
by
Ajean
on Stack Overflow
See other posts from Stack Overflow
or by Ajean
Published on 2014-08-12T19:37:47Z
Indexed on
2014/08/19
22:20 UTC
Read the original article
Hit count: 756
I'm hitting a very strange issue with matplotlib pick events. I have two artists that are both pickable and are non-overlapping to begin with ("holes" and "pegs"). When I pick one of them, during the event handling I move the other one to where I just clicked (moving a "peg" into the "hole"). Then, without doing anything else, a pick event from the moved artist (the peg) is generated even though it wasn't there when the first event was generated. My only explanation for it is that somehow the event manager is still moving through artist layers when the event is processed, and therefore hits the second artist after it is moved under the cursor.
So then my question is - how do pick events (or any events for that matter) iterate through overlapping artists on the canvas, and is there a way to control it? I think I would get my desired behavior if it moved from the top down always (rather than bottom up or randomly). I haven't been able to find sufficient enough documentation, and a lengthy search on SO has not revealed this exact issue. Below is a working example that illustrates the problem, with PathCollections
from scatter
as pegs and holes:
import matplotlib.pyplot as plt
import sys
class peg_tester():
def __init__(self):
self.fig = plt.figure(figsize=(3,1))
self.ax = self.fig.add_axes([0,0,1,1])
self.ax.set_xlim([-0.5,2.5])
self.ax.set_ylim([-0.25,0.25])
self.ax.text(-0.4, 0.15, 'One click on the hole, and I get 2 events not 1',
fontsize=8)
self.holes = self.ax.scatter([1], [0], color='black', picker=0)
self.pegs = self.ax.scatter([0], [0], s=100, facecolor='#dd8800',
edgecolor='black', picker=0)
self.fig.canvas.mpl_connect('pick_event', self.handler)
plt.show()
def handler(self, event):
if event.artist is self.holes:
# If I get a hole event, then move a peg (to that hole) ...
# but then I get a peg event also with no extra clicks!
offs = self.pegs.get_offsets()
offs[0,:] = [1,0] # Moves left peg to the middle
self.pegs.set_offsets(offs)
self.fig.canvas.draw()
print 'picked a hole, moving left peg to center'
elif event.artist is self.pegs:
print 'picked a peg'
sys.stdout.flush() # Necessary when in ipython qtconsole
if __name__ == "__main__":
pt = peg_tester()
I have tried setting the zorder to make the pegs always above the holes, but that doesn't change how the pick events are generated, and particularly this funny phantom event.
© Stack Overflow or respective owner