Hello all,

I've been working on some interactive graphs and have run into several problems 
with the pick_event feature:
(1) If a Figure Legend is made draggable() and then dropped onto an 
AxesSubplot, 
it can no longer be dragged
(2) Any lines associated with the left axis of a twinx() subplot are unable to 
be picked
(3) Hidden lines can be picked (seems like an undesirable feature).  Try 
picking 
on the top subplot at y=1 for a hidden line.

I know #2 has <a 
href="http://old.nabble.com/onpick-on-a-2-y-plot-%28-via-twinx%28%29-%29-seems-to-only-allow-picking-of-second-axes%27s-artists-td25049128.html";>caused
 problems for others</a>, with less than elegant solutions given.

Here's the code showing what is currently broken (as of v1.0.0):

#!/usr/bin/env python
import matplotlib as mpl
import pylab

# <-- Insert code to fix problem here

def on_pick(event):
    if isinstance(event.artist, mpl.legend.Legend):
        print 'Picked Legend'
    else:
        print 'Picked', event.artist.get_label(), event.ind

fig = pylab.figure()
ax = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
ax3 = ax2.twinx()
# Top subplot
ax.plot(range(10), range(10), c='r', marker='^', picker=5, label='Ramp')
line, = ax.plot(range(10), [1]*10, c='k', marker='o', picker=5, label='Hidden')
line.set_visible(False)
# Bottom subplot
legn_handles = []
legn_labels = []
line = ax2.plot(range(10), [1,3,1,3,0,3,1,3,1,3], c='b', marker='o', picker=5, 
label='Teeth')
legn_handles.append(line)
legn_labels.append('Teeth')
ax2.set_ylim(0, 4)
ax2.set_ylabel('Left side', color='b')
line = ax3.plot(range(10), [1,1,1,1,4,4,4,4,4,4], c='m', marker='.', picker=5, 
label='Shelf')
legn_handles.append(line)
legn_labels.append('Shelf')
ax3.set_ylim(0, 5)
ax3.set_ylabel('Right side', color='m')
# Subplot Legend for top plot
legn = ax.legend()
legn.draggable()
# Figure Legend
legn = fig.legend(legn_handles, legn_labels, 'lower right')
legn.draggable()
fig.canvas.mpl_connect('pick_event', on_pick)
pylab.show()
# 
--------------------------------------------------------------------------------------------



I've found a decent workaround, but it involves some very fundamental  changes 
to the way picking is resolved in the Figure and Axes classes.  If you add the 
following code to the spot indicated for the fix, everything works correctly.

# Fix for pick_event problems
def axes_pick(self, *args):
    if len(args)>1:
        raise DeprecationWarning('New pick API implemented -- '
                                 'see API_CHANGES in the src distribution')
    mouseevent = args[0]
    if not self.in_axes(mouseevent):
        return
    for a in self.get_children():
        if not a.get_visible():
            continue
        a.pick(mouseevent)
mpl.axes.Axes.pick = axes_pick

def figure_pick(self, mouseevent):
    for a in self.get_children():
        if not a.get_visible():
            continue
        a.pick(mouseevent)
mpl.figure.Figure.pick = figure_pick


To compare the differences, you need to look at the artist.Artist.pick() 
method.  It only calls pick() for children whose axes==mouseevent.inaxes or 
when 
inaxes is None (to handle the Legend).  But this fails when the Legend is 
dragged over a Subplot (inaxes no longer None), causing bug #1.  Also, 
mouseevent.inaxes only contains a single axes instance, which causes a failure 
for overlapping twinx() axes, hence bug #2.  And of course there is no check 
for 
hidden artists (#3).

My change calls pick() for every child of the Figure or Subplot, but then has 
the Subplot check whether the mouseevent is in its own axes space.  This seems 
to fix all the problems, but could potentially cause new bugs.  Any thoughts?  
I'm new to the mailing list, so I'm not sure how patches get applied and how 
much testing needs to be done for a change like this.

Thanks,
Jim



      

------------------------------------------------------------------------------
Free Software Download: Index, Search & Analyze Logs and other IT data in 
Real-Time with Splunk. Collect, index and harness all the fast moving IT data 
generated by your applications, servers and devices whether physical, virtual
or in the cloud. Deliver compliance at lower cost and gain new business 
insights. http://p.sf.net/sfu/splunk-dev2dev 
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to