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