From: Matt N. <new...@ca...> - 2005-03-23 17:04:45
|
Leighton, This also does not work Win XP.... The issue is that you're trying to update the data *before* running the MainLoop(). The puzzle should be why it works on Linux / GTK ;). There are a few approaches to the better solution, all of which lead to slightly more complex than your example. One such solution is below (and attached), using Start and Stop buttons, and a timer to periodically update the plot. I tried to add as little code to yours as possible, but also changed from backend_wx to backend_wxagg, because it's significantly faster and seemed to be your intent. I'm not sure the logic in update_data is really what you want, BTW. You might find the example in MPlot-0.7/examples/test.py at http://cars9.uchicago.edu/~newville/Python/MPlot helpful. This is a more complete example of dynamically updating a WXAgg canvas. It needs better documentation, but seems pretty close to what you're trying to do. Hope that helps, --Matt Newville import matplotlib matplotlib.use("WXAgg") matplotlib.interactive(True) from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg from matplotlib.figure import Figure from matplotlib.axes import Subplot from Numeric import pi, sin, arange import wx class PlotFigure(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "Test embedded wxFigure") self.fig = Figure((5,4), 75) self.canvas = FigureCanvasWxAgg(self, -1, self.fig) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.canvas, 1, wx.TOP) # create start/stop buttons self.button_start = wx.Button(self,-1, " Start ", size=(-1,-1)) self.button_stop = wx.Button(self,-1, " Stop ", size=(-1,-1)) # bind actions to the buttons self.button_start.Bind(wx.EVT_BUTTON,self.OnStart) self.button_stop.Bind(wx.EVT_BUTTON, self.OnStop) # pack the buttons in the Sizer btnsizer = wx.BoxSizer(wx.HORIZONTAL) btnsizer.Add(self.button_start, 1, wx.LEFT) btnsizer.Add(self.button_stop, 1, wx.LEFT) sizer.Add(btnsizer, 0, wx.TOP) self.SetSizer(sizer) self.Fit() # initialize the data here self.init_plot_data() # create a timer, used in OnStart / OnStop ID_TIMER = wx.NewId() wx.EVT_TIMER(self, ID_TIMER, self.onTimer) self.timer = wx.Timer(self, ID_TIMER) def init_plot_data(self): self.a = self.fig.add_subplot(111) x = arange(0,2*pi,0.01) # x-array self.a.set_xlim((0., 2*pi)) self.a.set_ylim((-1., 1.)) self.line, = self.a.plot(x,x) self.npts = len(x) def update_data(self,i): self.line.set_ydata(self.line.get_xdata()*0.01*i) self.canvas.draw() def onTimer(self, event): self.count += 1 if self.count > self.npts: self.OnStop() else: self.update_data(self.count) def OnStop(self,event=None): self.timer.Stop() def OnStart(self,event=None): self.count = 0 self.timer.Start(20) # delay in milliseconds if __name__ == '__main__': app = wx.PySimpleApp(0) frame = PlotFigure() frame.Show(True) app.MainLoop() |