Using mpl 0.98.5.2 in OO mode with wxAgg backend.

I'm trying to make my legends draggable.  It works, but
there is a some inaccuracy with positioning.  As I drag it,
the cursor "outruns" the position of the legend, and that
error grows the further away from the initial starting point
the cursor has been moved.  It makes the feel of dragging
completely wrong.

The work of repositioning the legend is done in an
on_motion event.  self.figure here is a mpl Figure.
The motion event handler is:

#drag the legend
    def on_motion(self, event):
        height = float(self.figure.bbox.height)
        width = float(self.figure.bbox.width)

        dx = event.x/width
        dy = event.y/height

        if self.gotLegend == 1:  #it's picked up
            self.legend._loc=(dx,dy)  #reposition it
            self.canvas.draw()
            self.parent.Refresh()

Any idea why this is wrong?  I cobbled this from
a few sources online and boiled it down to this.
I am confused as to why it should use dx and dy
instead of just the exact position of the mouse.

Any ideas are appreciated, and full runnable
sample is below.

Thanks,
Che


#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.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.gotLegend = 0  #to begin, legend is not picked.

        self._SetInitialSize()

        self.Bind(wx.EVT_SIZE, self._onSize)
        self.state = 'Initial'
        self.draw()

    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,2,3],[4,5,6],'o',picker=5)
        self.line_collections_list.append(line)

        #Legend
        self.legend = self.subplot.legend(self.line_collections_list,
['datum'], 'right',
           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:
            self.gotLegend = 1

    #drag the legend
    #(This doesn't work well enough)
    def on_motion(self, event):
        height = float(self.figure.bbox.height)
        width = float(self.figure.bbox.width)

        dx = event.x/width
        dy = event.y/height

        if self.gotLegend == 1:
            self.legend._loc=(dx,dy)
            self.canvas.draw()
            self.parent.Refresh()

    #release the legend
    def on_release(self, event):
        if self.gotLegend == 1:
            self.gotLegend = 0

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()
    frame = create(None)
    frame.Show()

    app.MainLoop()

------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to