2

I am trying to use MatPlotLib with WXPython. I find a nice example from http://www.cs.colorado.edu/~kena/classes/5448/s11/presentations/pearse.pdf because it show how to use 2 panels and it is well explained how to embed matplotlib. But I think it is missing some part, because the graphic isn't being initialized. How can I fix that?

import wx
import numpy
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

class TestFrame(wx.Frame):
    def __init__(self,parent,title):
        wx.Frame.__init__(self,parent,title=title,size=(500,500))
        self.sp = wx.SplitterWindow(self)
        self.p1 = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)
        self.p2 = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)
        self.sp.SplitVertically(self.p1,self.p2,100)
        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetStatusText('Oi')

class p1(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent,-1,size=(50,50))

        self.figure = matplotlib.figure.Figure()
        self.axes = self.figure.add_subplot(111)
        t = numpy.arange(0.0,10,1.0)
        s = [0,1,0,1,0,2,1,2,1,0]
        self.y_max = 1.0
        self.axes,plot(t,s)
        self.canvas = FigureCanvas(self,-1,self.figure)

app = wx.App(redirect=False)
frame = TestFrame(None, 'Hello World!')
frame.Show()
app.MainLoop()

Thanks.

1 Answer 1

2

You made class p1 with matplot but you didn't use it in TestFrame.

I changed some names to make it more clear

import wx
import numpy 
import matplotlib

from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

class TestFrame(wx.Frame):
    def __init__(self,parent,title):
        wx.Frame.__init__(self,parent,title=title,size=(500,500))
        self.sp = wx.SplitterWindow(self)
        self.p1 = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)
        self.p2 = MatplotPanel(self.sp)
        self.sp.SplitVertically(self.p1,self.p2,100)
        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetStatusText('Oi')

class MatplotPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent,-1,size=(50,50))

        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        t = numpy.arange(0.0,10,1.0)
        s = [0,1,0,1,0,2,1,2,1,0]
        self.y_max = 1.0
        self.axes.plot(t,s)
        self.canvas = FigureCanvas(self,-1,self.figure)

app = wx.App(redirect=False)
frame = TestFrame(None, 'Hello World!')
frame.Show()
app.MainLoop()

see also (as example) my answer to how to combine wxPython, matplotlib and Pyopengl

EDIT:

MatplotPanel with NavigationToolbar and wx.Button to change plot.

EDIT: 2022.01.03

As @Samuel said in comment: newer matplotlib needs NavigationToolbar2WxAgg instead of NavigationToolbar2Wx. See also matplotlib doc: Embedding in wx #2

# older matplotlib
#from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as NavigationToolbar

# newer matplotlib 
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar

class MatplotPanel(wx.Panel):
    
    def __init__(self, parent):     
        wx.Panel.__init__(self, parent,-1,size=(50,50))

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.sizer)
        
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.toolbar = NavigationToolbar(self.canvas)

        self.button = wx.Button(self, -1, "Change plot")
        self.button.Bind(wx.EVT_BUTTON, self.changePlot)
        
        self.sizer.Add(self.toolbar, 0, wx.EXPAND)
        self.sizer.Add(self.button, 0, wx.EXPAND)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        
        self.drawSin()
        self.current_draw = 'sin'
        
#       self.drawLines()

    def changePlot(self, event):
        
        if self.current_draw == 'sin' :
            self.drawLines()
            self.current_draw = 'lines'
        else: 
            self.drawSin()
            self.current_draw = 'sin'
            
        self.Layout()
        
    def drawLines(self):
    
        x = numpy.arange(0.0,10,1.0)
        y = [0,1,0,1,0,2,1,2,1,0]
        
        self.axes.clear()
        self.axes.plot(x, y)

    def drawSin(self):
    
        x = numpy.arange(0.0,10,0.1)
        y = numpy.sin(x)
        
        self.axes.clear()
        self.axes.plot(x, y)

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks @furas. I am new to Matplotlib and WxPython. How can I put the box with Home/Subplot/Zoom etc in this program? Normally it is automatically.
I add example with navigation toolbar.
I add wx.Button to change plot
Wow, nice, @furas. But for me the button is with problem. When I click nothing happens, but sometimes when I click to the Pan button first than it changes to line (but not vice-versa).
Add "Agg" to "NavigationToolbar2Wx" on the import line to fix an error with newer versions of matplotlib.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.