embedding matplotlib in wxpython

Soren soren.skou.nielsen at gmail.com
Thu Apr 26 02:23:53 EDT 2007


Hi,

I've been trying to embed matplotlib in wxpython. I want to be able to
put a figure (axes) in a wx.Panel and place it somewhere in my GUI.
The GUI should have other panels with buttons etc. that can control
the output on the figure. I've been looking at the examples from the
matplotlib website, but can't seem to get it to work..

Does anyone here have experience in embedding matplotlib in wxpython?

I have attached my code.. it makes two panels.. one with a matplotlib
plot, and one with a button.. but the plotpanel is just a small square
in the corner.... !! ..

Any help is appreciated!

Thanks,
Soren


Code:
-----------------------------------

import wx
import pylab
from matplotlib.numerix import arange, sin, cos, pi
import matplotlib

matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
matplotlib.interactive(False)

class App(wx.App):

    def OnInit(self):
        self.frame = MainFrame("BioXtas - Autoplotter", (50,60),
(700,700))
        self.frame.Show()

        return True

class MainFrame(wx.Frame):

    def __init__(self, title, pos, size):
        wx.Frame.__init__(self, None, -1, title, pos, size)

        pPanel = PlotPanel(self, -1)            # Plot panel

        bPanel = ButtonPanel(self, 100,500, (200,100))    # button
panel

        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(pPanel,0)
        sizer.Add(bPanel,0)

        self.SetSizer(sizer)

class ButtonPanel(wx.Panel):

    def __init__(self, Parent, xPos, yPos, insize):

        pos = (xPos, yPos)
        wx.Panel.__init__(self, Parent, -1, pos, style =
wx.RAISED_BORDER, size = insize)

        button = wx.Button(self, -1, 'HELLO!!', (10,10), (150,50))

class NoRepaintCanvas(FigureCanvasWxAgg):
    """We subclass FigureCanvasWxAgg, overriding the _onPaint method,
so that
    the draw method is only called for the first two paint events.
After that,
    the canvas will only be redrawn when it is resized.
    """
    def __init__(self, *args, **kwargs):
        FigureCanvasWxAgg.__init__(self, *args, **kwargs)
        self._drawn = 0

    def _onPaint(self, evt):
        """
        Called when wxPaintEvt is generated
        """
        if not self._isRealized:
            self.realize()

        if self._drawn < 2:
            self.draw(repaint = False)
            self._drawn += 1

        self.gui_repaint(drawDC=wx.PaintDC(self))


class PlotPanel(wx.Panel):

    def __init__(self, parent, id = -1, color = None,\
                 dpi = None, style = wx.NO_FULL_REPAINT_ON_RESIZE,
**kwargs):

        wx.Panel.__init__(self, parent, id = id, style = style,
**kwargs)

        self.figure = Figure(None, dpi)
        self.canvas = NoRepaintCanvas(self, -1, self.figure)
        self._resizeflag = True

        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._onSize)

        self._SetSize()

    def draw(self):
        if not hasattr(self, 'subplot'):
            self.subplot = self.figure.add_subplot(111)
            theta = arange(0, 45*2*pi, 0.02)
            rad = (0.8*theta/(2*pi)+1)
            r = rad*(8 + sin(theta*7+rad/1.8))
            x = r*cos(theta)
            y = r*sin(theta)
            #Now draw it
            self.subplot.plot(x,y, '-r')

    def _onSize(self, event):
        self._resizeflag = True

    def _onIdle(self, evt):
         if self._resizeflag:
             self._resizeflag = False
             self._SetSize()
             self.draw()

    def _SetSize(self, pixels = None):
        """
        This method can be called to force the Plot to be a desired
size, which defaults to
        the ClientSize of the panel
        """
        if not pixels:
            pixels = self.GetClientSize()
        self.canvas.SetSize(pixels)
        self.figure.set_figsize_inches(pixels[0]/
self.figure.get_dpi(),
        pixels[1]/self.figure.get_dpi())


if __name__ == "__main__":

    app = App(0)
    app.MainLoop()




More information about the Python-list mailing list