Hi All,

    a while ago, Che posted a nice example on how to drag a legend
with the mouse. I have upgraded to matplotlib 0.99.1 and it looks like
the nice example is not working anymore: for the life of me I can't
figure out what's wrong. I attach the runnable sample submitted
originally.

Any suggestion regarding what's wrong with the code?

Thank you in advance.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/
http://thedoomedcity.blogspot.com/
#Boa:Frame:Frame1

import wx

import matplotlib
matplotlib.interactive(True)
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure

def create(parent):
    return Frame1(parent)

[wxID_FRAME1, wxID_FRAME1NOTEBOOK1, wxID_FRAME1PANEL1, 
] = [wx.NewId() for _init_ctrls in range(3)]

class PlotPanel(wx.Panel):    
    def __init__(self, parent,id = -1, color = None,\
        dpi = None, style = wx.NO_FULL_REPAINT_ON_RESIZE, **kwargs):
        self.gotLegend = 0  #to begin, legend is not picked.
        
        self.parent = parent
        self.line_collections_list = []

        wx.Panel.__init__(self, parent, **kwargs)
        
        self.figure = Figure(None, dpi)
        self.canvas = FigureCanvasWxAgg( self, -1, self.figure )

        #Connect all the mpl events
        self.canvas.mpl_connect('motion_notify_event', self.on_motion)
        self.canvas.mpl_connect('pick_event', self.on_pick)
        self.canvas.mpl_connect('button_release_event', self.on_release)

        self._SetInitialSize()
        
        self.Bind(wx.EVT_SIZE, self._onSize)

        self.draw()

    #a few sizing issues, not relevant to this draggable legend point.
    def _onSize(self, event):
        self._SetSize()
        event.Skip()
        
    def _SetSize( self ):
        pixels = tuple( self.GetClientSize() )
        self.SetSize( pixels )
        self.canvas.SetSize( pixels )
        self.figure.set_size_inches( float( pixels[0] )/self.figure.get_dpi(),
                                     float( pixels[1] )/self.figure.get_dpi() )
    
    def _SetInitialSize(self,):
        pixels = self.parent.GetClientSize()
        self.canvas.SetSize(pixels)
        self.figure.set_size_inches( (pixels[0])/self.figure.get_dpi(), 
         (pixels[1])/self.figure.get_dpi(), forward=True )
        
    def draw(self): 
        self.subplot = self.figure.add_subplot(111)
        line, = self.subplot.plot([1],[6],'o',picker=5) 
        if self.gotLegend == 0:  #need to prevent it from keep appending each 
time if it is just moving legend.
            self.line_collections_list.append(line)    
        
        #Legend.
        self.legend = self.subplot.legend(self.line_collections_list, ['1'], 
numpoints=1)
        self.legend.set_picker(self.my_legend_picker)
        
    #pick up the legend patch
    def my_legend_picker(self, legend, event): 
        return self.legend.legendPatch.contains(event)   
    
    #pick the legend
    def on_pick(self, event):    
        legend = self.legend
        if event.artist == legend:
            bbox = self.legend.get_window_extent()  #gets the box of the legend.
            self.mouse_x = event.mouseevent.x  #get mouse coordinates at time 
of pick.
            self.mouse_y = event.mouseevent.y
            print 'mouse x position at pick time', self.mouse_x
            print 'mouse y position at pick time', self.mouse_y
            self.legend_x = bbox.xmin          #get legend coordinates at time 
of pick.
            self.legend_y = bbox.ymin 
            print 'Legend x position @ pick time = ', self.legend_x
            print 'Legend y position @ pick time= ', self.legend_y
            self.gotLegend = 1  #indicates we picked up the legend.

    #drag the legend
    def on_motion(self, event):  
        if self.gotLegend == 1:
            x = mouse_diff_x = self.mouse_x - event.x  #how much the mouse 
moved.
            y = mouse_diff_y = self.mouse_y - event.y
            
            print 'motion_event.x =', event.x
            print 'motion_event.y =', event.y
            print 'mouse moved x = ', mouse_diff_x
            print 'mouse moved y = ', mouse_diff_y
            
            #move the legend from its previous location by that same amount
            loc_in_canvas = self.legend_x - mouse_diff_x, self.legend_y - 
mouse_diff_y
            #transform into legend coordinate system
            loc_in_norm_axes = 
self.legend.parent.transAxes.inverted().transform_point(loc_in_canvas)
            self.legend._loc = tuple(loc_in_norm_axes)
            
            self.canvas.draw()
        
    #release the legend    
    def on_release(self, event):
        if self.gotLegend == 1:
            self.gotLegend = 0
            print 'legend released'
            
class Frame1(wx.Frame):
    def _init_coll_boxSizer1_Items(self, parent):
        # generated method, don't edit

        parent.AddWindow(self.notebook1, 1, border=0, flag=wx.EXPAND)

    def _init_sizers(self):
        # generated method, don't edit
        self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)

        self._init_coll_boxSizer1_Items(self.boxSizer1)

        self.panel1.SetSizer(self.boxSizer1)

    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,
              pos=wx.Point(333, 202), size=wx.Size(592, 474),
              style=wx.DEFAULT_FRAME_STYLE,
              title='moving the legend accurately')
        self.SetClientSize(wx.Size(584, 440))

        self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,
              pos=wx.Point(0, 0), size=wx.Size(584, 440),
              style=wx.TAB_TRAVERSAL)

        self.notebook1 = wx.Notebook(id=wxID_FRAME1NOTEBOOK1, name='notebook1',
              parent=self.panel1, pos=wx.Point(0, 0), size=wx.Size(584, 440),
              style=0)

        self._init_sizers()

    def __init__(self, parent):
        self._init_ctrls(parent)
        graph = PlotPanel(self.notebook1)     
        self.notebook1.AddPage(graph,'graph')

if __name__ == '__main__':
    app = wx.PySimpleApp(0)  #set to wx.PySimpleApp() for no stdout window.
    frame = create(None)
    frame.Show()

    app.MainLoop()
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to