I'm writing a wx/matplotlib application, and I'm having considerable difficulty adding a new tool to the matplotlib NavigationToolbar.
Basically I want to add tools for selection (marquee, lasso, etc) that will toggle the controlled subplots mouse mode. As of yet I have been unable to find any features that will let me do this easily.
I did, however, just discover this function that looked like it would be helpful: http://matplotlib.sourceforge.net/api/axes_api.html?highlight=set_navigate_mode#matplotlib.axes.Axes.set_navigate_mode
Unfortunately, as the warning implies, it doesn't really help me.
Does anybody have a clue of how to do this? Below is a stripped down example showing how far I've gotten. The bookmark icon is used in place of my lasso icon, and I've removed the lasso functionality for brevity.
import wx
from matplotlib.patches import Rectangle
from matplotlib.widgets import Lasso
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
class ScatterPanel(FigureCanvasWxAgg):
'''
Contains the guts for drawing scatter plots.
'''
def __init__(self, parent, **kwargs):
self.figure = Figure()
FigureCanvasWxAgg.__init__(self, parent, -1, self.figure, **kwargs)
self.canvas = self.figure.canvas
self.SetMinSize((100,100))
self.figure.set_facecolor((1,1,1))
self.figure.set_edgecolor((1,1,1))
self.canvas.SetBackgroundColour('white')
self.subplot = self.figure.add_subplot(111)
self.navtoolbar = None
self.lasso = None
self.redraw()
self.canvas.mpl_connect('button_press_event', self.on_press)
self.canvas.mpl_connect('button_release_event', self.on_release)
def lasso_callback(self, verts):
pass
def on_press(self, evt):
if evt.button == 1:
if self.canvas.widgetlock.locked():
return
if evt.inaxes is None:
return
if self.navtoolbar.mode == 'lasso':
self.lasso = Lasso(evt.inaxes, (evt.xdata, evt.ydata), self.lasso_callback)
self.canvas.widgetlock(self.lasso)
def on_release(self, evt):
# Note: lasso_callback is not called on click without drag so we release
# the lock here to handle this case as well.
if evt.button == 1:
if self.lasso:
self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso)
self.lasso = None
else:
self.show_popup_menu((evt.x, self.canvas.GetSize()[1]-evt.y), None)
def redraw(self):
self.subplot.clear()
self.subplot.scatter([1,2,3],[3,1,2])
def toggle_lasso_tool(self, evt):
if evt.Checked():
self.navtoolbar.mode = 'lasso'
#self.subplot.set_navigate_mode('lasso')
# Cheat: untoggle the zoom and pan tools
self.navtoolbar.ToggleTool(self.navtoolbar._NTB2_ZOOM, False)
self.navtoolbar.ToggleTool(self.navtoolbar._NTB2_PAN, False)
else:
self.navtoolbar.mode = ''
self.lasso = None
#self.subplot.set_navigate_mode('')
def get_toolbar(self):
if not self.navtoolbar:
self.navtoolbar = NavigationToolbar(self.canvas)
self.navtoolbar.DeleteToolByPos(6)
ID_LASSO_TOOL = wx.NewId()
lasso = self.navtoolbar.InsertSimpleTool(5, ID_LASSO_TOOL,
wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK),
isToggle=True)
self.navtoolbar.Realize()
self.navtoolbar.Bind(wx.EVT_TOOL, self.toggle_lasso_tool, id=ID_LASSO_TOOL)
return self.navtoolbar
if __name__ == "__main__":
app = wx.PySimpleApp()
f = wx.Frame(None, size=(600,600))
p = ScatterPanel(f)
f.SetToolBar(p.get_toolbar())
f.Show()
app.MainLoop()
Thanks, Adam