【发布时间】:2023-03-03 09:49:02
【问题描述】:
我正在编写一个 wx/matplotlib 应用程序,并且在向 matplotlib NavigationToolbar 添加新工具时遇到了相当大的困难。
基本上,我想添加用于切换受控子图鼠标模式的选择工具(选框、套索等)。到目前为止,我还没有找到任何可以让我轻松做到这一点的功能。
不过,我确实发现了这个看起来很有帮助的功能:http://matplotlib.sourceforge.net/api/axes_api.html?highlight=set_navigate_mode#matplotlib.axes.Axes.set_navigate_mode
不幸的是,正如警告所暗示的那样,它并没有真正帮助我。
有人知道如何做到这一点吗?下面是一个精简的例子,展示了我已经走了多远。书签图标用于代替我的套索图标,为了简洁起见,我删除了套索功能。
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()
谢谢, 亚当
【问题讨论】:
标签: python matplotlib toolbar