#!/usr/bin/env python
"""
Show how to have wx draw a cursor over an axes that moves with the
mouse and reports the data coords
"""
from matplotlib.numerix import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
from wxPython.wx import *
class CanvasFrame(wxFrame):
def __init__(self):
wxFrame.__init__(self,None,-1,
'CanvasFrame',size=(550,350))
self.SetBackgroundColour(wxNamedColor("WHITE"))
self.figure = Figure()
self.axes = self.figure.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)
self.axes.plot(t,s)
self.axes.set_xlabel('Time (s)')
self.axes.set_ylabel('Price ($)')
self.canvas = FigureCanvas(self, -1, self.figure)
self.canvas.mpl_connect('motion_notify_event', self.mouse_move)
self.sizer = wxBoxSizer(wxVERTICAL)
self.sizer.Add(self.canvas, 1, wxLEFT | wxTOP | wxGROW)
self.SetSizer(self.sizer)
self.Fit()
self.statusBar = wxStatusBar(self, -1)
self.statusBar.SetFieldsCount(1)
self.SetStatusBar(self.statusBar)
self.add_toolbar() # comment this out for no toolbar
EVT_PAINT(self, self.OnPaint)
def mouse_move(self, event):
self.draw_cursor(event)
def add_toolbar(self):
self.toolbar = NavigationToolbar2Wx(self.canvas)
self.toolbar.Realize()
tw, th = self.toolbar.GetSizeTuple()
fw, fh = self.canvas.GetSizeTuple()
self.toolbar.SetSize(wxSize(fw, th))
self.sizer.Add(self.toolbar, 0, wxLEFT | wxEXPAND)
# update the axes menu on the toolbar
self.toolbar.update()
def OnPaint(self, event):
self.erase_cursor()
try: del self.lastInfo
except AttributeError: pass
self.canvas.draw()
event.Skip()
def draw_cursor(self, event):
'event is a MplEvent. Draw a cursor over the axes'
if event.inaxes is None:
self.erase_cursor()
try: del self.lastInfo
except AttributeError: pass
return
canvas = self.canvas
figheight = canvas.figure.bbox.height()
ax = event.inaxes
left,bottom,width,height = ax.bbox.get_bounds()
bottom = figheight-bottom
top = bottom - height
right = left + width
x, y = event.x, event.y
y = figheight-y
dc = wxClientDC(canvas)
dc.SetLogicalFunction(wxXOR)
wbrush = wxBrush(wxColour(255,255,255), wxTRANSPARENT)
wpen = wxPen(wxColour(200, 200, 200), 1, wxSOLID)
dc.SetBrush(wbrush)
dc.SetPen(wpen)
dc.ResetBoundingBox()
dc.BeginDrawing()
x, y, left, right, bottom, top = [int(val) for val in x, y, left, right, bottom, top]
self.erase_cursor()
line1 = (x, bottom, x, top)
line2 = (left, y, right, y)
self.lastInfo = line1, line2, ax, dc
dc.DrawLine(*line1) # draw new
dc.DrawLine(*line2) # draw new
dc.EndDrawing()
time, price = event.xdata, event.ydata
self.statusBar.SetStatusText("Time=%f Price=%f"% (time, price), 0)
def erase_cursor(self):
try: lastline1, lastline2, lastax, lastdc = self.lastInfo
except AttributeError: pass
else:
lastdc.DrawLine(*lastline1) # erase old
lastdc.DrawLine(*lastline2) # erase old
class App(wxApp):
def OnInit(self):
'Create the main window and insert the custom frame'
frame = CanvasFrame()
frame.Show(true)
return true
app = App(0)
app.MainLoop()