【发布时间】:2018-04-30 20:55:13
【问题描述】:
我正在 wxPython(Phoenix 4.0.1)和 Python 3.6.4 中使用 Matplotlib API(2.2.2)做一个简单的嵌入式图表。我对 WXAgg 导航工具栏进行了子类化,因此我可以删除“配置子图”工具,这工作正常。
此外,我在子类工具栏中添加了一个只读 TextCtrl 以显示鼠标坐标(就像它出现在基于 pyplot 状态的 matplotlib 版本中一样)。我根据 Matplotlib 文档为鼠标移动事件实现了一个简单的处理程序,这在 Windows 10 上一切正常。
但是,此代码无法在 macOS(10.13.4 High Sierra)上完全运行。图形显示得很好,工具栏显示得很好,工具栏按钮工作得很好,但是我没有在工具栏中显示任何带有鼠标坐标的 TextCtrl(甚至是创建 TextCtrl 时设置的初始值)。
谁能解释为什么 Matplotlib 工具栏中的 TextCtrl 在 Mac 上不起作用?有没有办法在mac上做到这一点?如果这根本不可能,那么在我的 Matplotlib 画布的其他地方显示鼠标坐标的替代方法是什么?
这是我的示例代码:
import wx
from matplotlib.figure import Figure
from matplotlib import gridspec
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx as NavigationToolbar
class MyToolbar(NavigationToolbar):
def __init__(self, plotCanvas):
# create the default toolbar
NavigationToolbar.__init__(self, plotCanvas)
# Add a control to display mouse coordinates
self.info = wx.TextCtrl(self, -1, value = 'Coordinates', size = (100,-1),
style = wx.TE_READONLY | wx.BORDER_NONE)
self.AddStretchableSpace()
self.AddControl(self.info)
# Remove configure subplots
SubplotsPosition = 6
self.DeleteToolByPos(SubplotsPosition)
self.Realize()
class Graph(wx.Frame):
def __init__(self, parent, title='Coordinates Test'):
super().__init__(parent, title=title)
self.SetSize((900, 500))
# A simple embedded matplotlib graph
self.fig = Figure(figsize = (8.2,4.2), facecolor = 'gainsboro')
self.canvas = FigureCanvas(self, -1, self.fig)
gs = gridspec.GridSpec(2, 1, left = .12, right = .9, bottom = 0.05, top = .9, height_ratios = [10, 1], hspace = 0.35)
ax = self.fig.add_subplot(gs[0])
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
ax.plot(t, s)
ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='About as simple as it gets, folks')
ax.grid()
ax.set_navigate(True)
# Get a toolbar instance
self.toolbar = MyToolbar(self.canvas)
self.toolbar.Realize()
# Connect to matplotlib for mouse movement events
self.canvas.mpl_connect('motion_notify_event', self.onMotion)
self.toolbar.update()
# Layout the frame
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas, 1, wx.LEFT | wx.EXPAND)
self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
self.SetSizer(self.sizer)
def onMotion(self, event):
if event.inaxes:
xdata = event.xdata
ydata = event.ydata
self.toolbar.info.ChangeValue(f'x = {xdata:.1f}, y = {ydata:.1f}')
else:
self.toolbar.info.ChangeValue('')
class MyFrame(wx.Frame):
def __init__(self, parent, title=""):
super().__init__(parent, title=title)
self.SetSize((800, 480))
self.graph = Graph(self)
self.graph.Show()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, title='Main Frame')
self.frame.Show()
return True
if __name__ == "__main__":
app = MyApp(False)
app.MainLoop()
【问题讨论】:
标签: macos matplotlib wxpython