[wxPython-users] matplotlib & wxPython question
Christopher Barker
Chris.Barker at noaa.gov
Thu Jan 24 15:42:31 PST 2008
1) You might get better luck on the MPL list for this -- you seem to
have done the embedding right, so it's really an MPL issue.
2) You can change the data on a line object in MPL, without calling plot
again, so you can re-use all the existing axis, etc, etc. That may be
faster and more robust.
3) Check out wxMPL for embedding MPL in wx -- it does some of the work
for you, and has some nice features.
-Chris
Assaf Tal wrote:
> Hi people,
>
>
>
> I hope I've come to the right place - if not please redirect me :).
>
> I've been trying to get matplotlib & wxPython to work together. I've
> pretty much succeeded - I've written a program (attached below) which
> plots a sine function, with a slider controlling the number of cycles.
> So far so good.
>
> However, after moving the slider around for several seconds, the program
> suddenly starts spewing out error messages in the console. The program
> itself doesn't close or crash, but the plot stops updating itself.
>
> Can you help me understand the problem and fix it? Is it a memory thing,
> or perhaps something else?
>
> Thank you very much for your help!
>
>
> Assaf.
>
> Short note: the "important" parts are the PlotPanel class, with its
> init_plot_data which gets called every time the slider is moved, and the
> OnSlider function of the main frame, which is bound to the
> slider-movement event.
> Other than that, the program consists of two panes separated by a sash.
> I'm using PSPAD to edit my files, and run my programs using Python.exe
> on a windows XP operating system.
>
> ---------------------------------------------------------------- Begin
> attachment
> ------------------------------------------------------------------------
>
> #!/usr/bin/env python
>
> import matplotlib
> matplotlib.use('WXAgg')
> from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg
>
> from matplotlib.figure import Figure
> import numpy as npy
> import wx
>
>
> class PlotPanel(wx.Panel):
> """ This class represents a basic embelishment on the wx.Panel
> class, allowing for plots. """
>
> def __init__(self, parent):
> wx.Panel.__init__(self, parent, -1)
> self.fig = Figure()
> self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
> self.figHandle = self.fig.add_subplot(111)
> # Now put all into a sizer
> sizer = wx.BoxSizer(wx.VERTICAL)
> # This way of adding to sizer allows resizing
> sizer.Add(self.canvas, 1, wx.LEFT|wx.TOP|wx.GROW)
> self.SetSizer(sizer)
> self.Fit()
>
> def init_plot_data(self,x = [1,2,3,4], y = [1,2,3,4]):
> self.figHandle.clear()
> self.figHandle.plot(x,y)
> self.canvas.draw()
>
> class MyFrame(wx.Frame):
> def __init__(self, parent = None, id = -1, pos = (10,10), title =
> "HelloWorld", size = (800,600)):
> wx.Frame.__init__(self, parent,id,title, pos, size)
> self.CreateMenu()
> # Create a status bar
> self.CreateStatusBar()
> # Create the toolbar
> self.AddToolBar()
> # Create splitter window
> self.initpos = 70
> self.sp = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
> # First panel is for the slider
> self.p1 = wx.Panel(self.sp)
> # Second panel is for plotting
> self.p2 = PlotPanel(self.sp)
> self.p2.Hide()
> self.p1.SetBackgroundColour("cornflower blue")
> self.p2.SetBackgroundColour("sky blue")
> self.sp.Initialize (self.p1)
> self.sp.SetMinimumPaneSize(10)
> self.sp.SplitHorizontally(self.p1, self.p2, self.initpos)
> # Create user input slider
> self.slider = wx.Slider(self.p1, 100, 25, 1, 100, pos=(10,10),
> size=(250,-1), style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS)
> self.slider.SetTickFreq(10,1)
> self.slider.SetForegroundColour("white")
> self.Bind(wx.EVT_SLIDER, self.OnSlider, self.slider)
> self.slider.CentreOnParent()
> # Create plotting panel
> self.p2.init_plot_data()
>
>
> def CreateMenu(self):
> # Define menus
> menuFile = wx.Menu()
> menuHelp = wx.Menu()
> # Add items
> menuFile.Append(1, "&Open...")
> menuFile.AppendSeparator()
> menuFile.Append(3, "E&xit")
> menuHelp.Append(1, "&About")
> # Create the menu bar
> menuBar = wx.MenuBar()
> menuBar.Append(menuFile,"&File")
> menuBar.Append(menuHelp,"&Help")
> # Add to frame
> self.SetMenuBar(menuBar)
>
> def AddToolBar(self):
> toolbar = self.CreateToolBar(wx.NO_BORDER)
> toolbar.SetToolBitmapSize((32,32))
> for each in self.ToolBarData():
> if not each[0]:
> toolbar.AddSeparator()
> else:
> bmp = wx.Image(each[1],
> wx.BITMAP_TYPE_PNG).ConvertToBitmap()
> toolbar.AddSimpleTool(-1,bmp, each[0], each[2]);
> toolbar.Realize()
>
> def ToolBarData(self):
> return (("Open", "folder.png", "Open a WAV file", self.OnOpen),
> ("Play", "media-playback-start.png ", "Play current
> file", self.OnPlay),
> ("", "", "", ""),
> ("Help", "help-browser.png", "Browse online help",
> self.OnHelp))
>
> def OnOpen():
> pass
>
> def OnPlay():
> pass
>
> def OnHelp():
> pass
>
> def OnSlider(self, event):
> sliderValue = self.slider.GetValue()
> self.SetStatusText('Ive been moved!')
> curX = npy.arange(0,10,0.05)
> curY = npy.sin(sliderValue*curX)
> self.p2.init_plot_data(curX,curY)
>
>
>
>
> class App(wx.App):
> def OnInit(self):
> self.frame = MyFrame()
> self.frame.Show()
> self.SetTopWindow(self.frame)
> return True
>
> def main():
> app = App(False)
> app.MainLoop()
>
> if __name__ == '__main__':
> main()
>
>
>
> ------------------------------------------------------------------- End
> attachment
> ------------------------------------------------------------------------
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker at noaa.gov
More information about the wxpython-users
mailing list