简体   繁体   中英

Matplotlib/wxpython: co-ordinate values not showing up in status bar

I have a simple matplotlib plot integrated with wxPython, and for some reason the x/y co-ordinates are not showing up under the status bar (the co-ordinates that show when you move the mouse), they used to appear but cannot get it to happen anymore. Any ideas why this may be possible? (I've also tried setting the format_coord attribute manually but that doesn't seem to work).

I think it's wx doing something funny, since if I just create a matplotlib plot in a new Python shell it works fine. Example code is below:

#Subclassing WX Panel Class to be able to integrate matplotlib into it
class p1(wx.Panel):
    def __init__(self, parent, frame):

        #Initialize WX Panel
        wx.Panel.__init__(self, parent, -1, size=(50,50))

        #Set up Figure/Canvas
        self.frame = frame
        self.figure = Figure()
        self.canvas = FigureCanvas(self, -1, self.figure)

        #Set up Matplotlib Toolbar
        self.chart_toolbar = NavigationToolbar2Wx(self.canvas)
        tw,th = self.chart_toolbar.GetSizeTuple()
        fw,fh = self.canvas.GetSizeTuple()
        self.chart_toolbar.SetSize(wx.Size(fw, th))
        self.chart_toolbar.Realize()

        graphs_sizer = wx.BoxSizer(wx.VERTICAL)

        graphs_sizer.Add(self.canvas, 20, flag=wx.EXPAND, border=5)
        graphs_sizer.Add(self.chart_toolbar, 1, flag=wx.ALIGN_CENTER, border=5)

        self.SetSizer(graphs_sizer)

    def plot(self):
        self.axs1 = self.figure.add_subplot(1,1,1)
        self.axs1.plot([1,2,3,4,5],color='blue')

class TestFrame(wx.Frame):
    def __init__(self, parent, title):

        #Initialize WX Frame
        wx.Frame.__init__(self, parent, title=title, size=(1000,800))

        #Create Splitter Window and Add Left/Right Panels
        self.splitterWindow = wx.SplitterWindow(self)
        self.panel1 = p1(self.splitterWindow, self)
        self.panel2 = wx.Panel(self.splitterWindow)
        self.splitterWindow.SplitVertically(self.panel1, self.panel2, 700)

        #Create Status Bar
        self.statusbar = self.CreateStatusBar()

        #Plot
        self.panel1.plot()

app = wx.App(redirect=False)
frame = TestFrame(None, "Test")
frame.Show(True)
app.MainLoop()

whereas something as simple as this works fine:

plt.plot([1,2,3,4,5])
plt.show()

It is easier for people to help if you make the code complete, ie with the imports in your case.

Note that you don't need the "SetSize" stuff for the toolbar, IIRC that was only needed with some wxPython versions on MAC.

To get the mouse coordinates you need to connect an event, that might be done out of the box with plt.plot.

Doc for the events is here: http://matplotlib.org/users/event_handling.html

import wx

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

#Subclassing WX Panel Class to be able to integrate matplotlib into it
class p1(wx.Panel):
    def __init__(self, parent, frame):

        #Initialize WX Panel
        wx.Panel.__init__(self, parent, -1, size=(50,50))

        #Set up Figure/Canvas
        self.frame = frame
        self.figure = Figure()
        self.canvas = FigureCanvas(self, -1, self.figure)

        #Set up Matplotlib Toolbar
        self.chart_toolbar = NavigationToolbar2Wx(self.canvas)
        self.chart_toolbar.Realize()

        graphs_sizer = wx.BoxSizer(wx.VERTICAL)

        graphs_sizer.Add(self.canvas, 20, flag=wx.EXPAND, border=5)
        graphs_sizer.Add(self.chart_toolbar, 1, flag=wx.ALIGN_CENTER, border=5)

        self.SetSizer(graphs_sizer)

    def plot(self):
        self.axs1 = self.figure.add_subplot(1,1,1)
        self.axs1.plot([1,2,3,4,5],color='blue')

class TestFrame(wx.Frame):
    def __init__(self, parent, title):

        #Initialize WX Frame
        wx.Frame.__init__(self, parent, title=title, size=(1000,800))

        #Create Splitter Window and Add Left/Right Panels
        self.splitterWindow = wx.SplitterWindow(self)
        self.panel1 = p1(self.splitterWindow, self)
        self.panel2 = wx.Panel(self.splitterWindow)
        self.splitterWindow.SplitVertically(self.panel1, self.panel2, 700)

        #Create Status Bar
        self.statusbar = self.CreateStatusBar()

        #Plot
        self.panel1.plot()

        mouseMoveID = self.panel1.canvas.mpl_connect('motion_notify_event',
                                                     self.onMotion)

    def onMotion(self, evt):
        x = evt.x
        y = evt.y
        inaxes = evt.inaxes
        xdata = evt.xdata
        ydata = evt.ydata
        self.statusbar.SetStatusText("%s, %s, %s, %s, %s" % (
            x, y, inaxes, xdata, ydata))


app = wx.App(redirect=False)
frame = TestFrame(None, "Test")
frame.Show(True)
app.MainLoop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM