1 #!/usr/bin/env python
\r
6 Plot panel for Hooke.
\r
8 Copyright 2009 by Dr. Rolf Schmidt (Concordia University, Canada)
\r
10 This program is released under the GNU General Public License version 2.
\r
13 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
\r
15 from matplotlib.backends.backend_wx import NavigationToolbar2Wx
\r
17 from matplotlib.figure import Figure
\r
21 #there are many comments in here from the demo app
\r
22 #they should come in handy to expand the functionality in the future
\r
24 class HookeCustomToolbar(NavigationToolbar2Wx):
\r
26 def __init__(self, plotCanvas):
\r
27 NavigationToolbar2Wx.__init__(self, plotCanvas)
\r
28 # add new toolbar buttons
\r
29 #glyph_file = 'resources' + os.sep + 'pipette.png'
\r
30 #glyph = wx.Image(glyph_file, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
\r
32 #self.AddCheckTool(ON_CUSTOM_PICK, glyph, shortHelp='Select a data point', longHelp='Select a data point')
\r
33 #wx.EVT_TOOL(self, ON_CUSTOM_PICK, self.OnSelectPoint)
\r
35 # remove the unwanted button
\r
36 # POSITION_OF_CONFIGURE_SUBPLOTS_BTN = 6
\r
37 # self.DeleteToolByPos(POSITION_OF_CONFIGURE_SUBPLOTS_BTN)
\r
39 #def OnSelectPoint(self, event):
\r
40 #self.Parent.Parent.Parent.pick_active = True
\r
44 #def __init__(self, line):
\r
46 #self.xs = list(line.get_xdata())
\r
47 #self.ys = list(line.get_ydata())
\r
48 #self.cid = line.figure.canvas.mpl_connect('button_press_event', self)
\r
50 #def __call__(self, event):
\r
51 #print 'click', event
\r
52 #if event.inaxes != self.line.axes:
\r
54 #self.xs.append(event.xdata)
\r
55 #self.ys.append(event.ydata)
\r
56 #self.line.set_data(self.xs, self.ys)
\r
57 #self.line.figure.canvas.draw()
\r
60 class PlotPanel(wx.Panel):
\r
62 def __init__(self, parent, ID):
\r
63 wx.Panel.__init__(self, parent, ID, style=wx.WANTS_CHARS|wx.NO_BORDER, size=(160, 200))
\r
65 self.figure = Figure()
\r
66 self.canvas = FigureCanvas(self, -1, self.figure)
\r
67 self.SetColor(wx.NamedColor('WHITE'))
\r
69 self.sizer = wx.BoxSizer(wx.VERTICAL)
\r
70 self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
\r
71 self.SetSizer(self.sizer)
\r
74 self.display_coordinates = False
\r
76 self.figure.canvas.mpl_connect('button_press_event', self.OnClick)
\r
77 self.figure.canvas.mpl_connect('axes_enter_event', self.OnEnterAxes)
\r
78 self.figure.canvas.mpl_connect('axes_leave_event', self.OnLeaveAxes)
\r
79 self.figure.canvas.mpl_connect('motion_notify_event', self.OnMouseMove)
\r
80 self.add_toolbar() # comment this out for no toolbar
\r
82 def add_toolbar(self):
\r
83 self.toolbar = HookeCustomToolbar(self.canvas)
\r
84 self.toolbar.Realize()
\r
85 if wx.Platform == '__WXMAC__':
\r
86 # Mac platform (OSX 10.3, MacPython) does not seem to cope with
\r
87 # having a toolbar in a sizer. This work-around gets the buttons
\r
88 # back, but at the expense of having the toolbar at the top
\r
89 self.SetToolBar(self.toolbar)
\r
91 # On Windows platform, default window size is incorrect, so set
\r
92 # toolbar width to figure width.
\r
93 tw, th = self.toolbar.GetSizeTuple()
\r
94 fw, fh = self.canvas.GetSizeTuple()
\r
95 # By adding toolbar in sizer, we are able to put it at the bottom
\r
96 # of the frame - so appearance is closer to GTK version.
\r
97 # As noted above, doesn't work for Mac.
\r
98 self.toolbar.SetSize(wx.Size(fw, th))
\r
99 self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
\r
100 # update the axes menu on the toolbar
\r
101 self.toolbar.update()
\r
103 def get_figure(self):
\r
106 def SetColor(self, rgbtuple):
\r
108 Set figure and canvas colours to be the same
\r
111 rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
\r
112 col = [c / 255.0 for c in rgbtuple]
\r
113 self.figure.set_facecolor(col)
\r
114 self.figure.set_edgecolor(col)
\r
115 self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
\r
117 def SetStatusText(self, text, field=1):
\r
118 self.Parent.Parent.statusbar.SetStatusText(text, field)
\r
120 def OnClick(self, event):
\r
121 #self.SetStatusText(str(event.xdata))
\r
122 #print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(event.button, event.x, event.y, event.xdata, event.ydata)
\r
125 def OnEnterAxes(self, event):
\r
126 self.display_coordinates = True
\r
128 def OnLeaveAxes(self, event):
\r
129 self.display_coordinates = False
\r
130 self.SetStatusText('')
\r
132 def OnMouseMove(self, event):
\r
133 if event.guiEvent.m_shiftDown:
\r
134 self.toolbar.set_cursor(2)
\r
135 #print 'hand: ' + str(wx.CURSOR_HAND)
\r
136 #print 'cross: ' + str(wx.CURSOR_CROSS)
\r
137 #print 'ibeam: ' + str(wx.CURSOR_IBEAM)
\r
138 #print 'wait: ' + str(wx.CURSOR_WAIT)
\r
139 #print 'hourglass: ' + str(wx.HOURGLASS_CURSOR)
\r
141 self.toolbar.set_cursor(1)
\r
143 #axes = self.figure.axes[0]
\r
144 #line, = axes.plot([event.x - 20 , event.x + 20], [event.y - 20, event.y + 20])
\r
146 #line.figure.canvas.draw()
\r
147 if self.display_coordinates:
\r
148 coordinateString = ''.join(['x: ', str(event.xdata), ' y: ', str(event.ydata)])
\r
149 #TODO: pretty format
\r
150 self.SetStatusText(coordinateString)
\r
152 def OnPaint(self, event):
\r