From: Leighton P. <lp...@sc...> - 2005-03-23 14:53:06
|
Hi,=0D=0A=0D=0AI'm having difficulty producing dynamic plots on OS X using = matplotlib=0D=0A0.73.1 and wxPython 2.5.3.1 on OS X 10.3 with Python 2.3.5=0D= =0A=0D=0AThe code below works with the same configuration on Fedora Core 3,=0D= =0Aproducing a graph with a line that pivots at the origin. On OS X,=0D=0A= however, the frame remains blank and grey until the final plot is drawn,=0D= =0Awhen the plot takes on the correct final state.=0D=0A=0D=0AI've tried si= milar examples with bar graphs and scatter plots, and the=0D=0Asame results= are produced. I don't know if this is a problem with=0D=0Amatplotlib or w= xPython, and any help would be gratefully appreciated.=0D=0A=0D=0AIf you ne= ed any more info to help, let me know.=0D=0A=0D=0AThe example code is:=0D=0A=0D= =0A----------------=0D=0A=0D=0Aimport matplotlib=0D=0Amatplotlib.use("WXAgg= ")=0D=0Amatplotlib.interactive(True)=0D=0Afrom matplotlib.backends.backend_= wx import FigureCanvasWx=0D=0Afrom matplotlib.figure import Figure=0D=0Afro= m matplotlib.axes import Subplot=0D=0A=0D=0Afrom Numeric import pi, sin, ar= ange=0D=0A=0D=0Aimport wx=0D=0A=0D=0A=0D=0Aclass PlotFigure(wx.Frame):=0D=0A= def __init__(self):=0D=0A wx.Frame.__init__(self, None, -1, "Tes= t embedded wxFigure")=0D=0A=0D=0A self.fig =3D Figure((5,4), 75)=0D=0A= self.canvas =3D FigureCanvasWx(self, -1, self.fig)=0D=0A=0D=0A = sizer =3D wx.BoxSizer(wx.VERTICAL)=0D=0A sizer.Add(self.canvas, 1= , wx.LEFT|wx.TOP|wx.GROW)=0D=0A self.SetSizer(sizer)=0D=0A se= lf.Fit()=0D=0A=0D=0A def init_plot_data(self):=0D=0A self.a =3D s= elf.fig.add_subplot(111)=0D=0A x =3D arange(0,2*pi,0.01) #= x-array=0D=0A self.a.set_xlim((0., 2*pi))=0D=0A self.a.set_y= lim((-1., 1.))=0D=0A self.line, =3D self.a.plot(x,x)=0D=0A=0D=0A = def update_data(self, i):=0D=0A self.line.set_ydata(self.line.get_xd= ata()*0.01*i)=0D=0A self.canvas.draw()=0D=0A=0D=0A=0D=0Aif __name__ = =3D=3D '__main__':=0D=0A app =3D wx.PySimpleApp(0)=0D=0A frame =3D Pl= otFigure()=0D=0A frame.Show(True)=0D=0A frame.init_plot_data()=0D=0A = for i in arange(1,200):=0D=0A frame.update_data(i)=0D=0A app.M= ainLoop()=0D=0A=0D=0A=0D=0A=0D=0A--=20=0D=0ADr Leighton Pritchard AMRSC=0D=0A= D131, Plant-Pathogen Interactions, Scottish Crop Research Institute=0D=0AIn= vergowrie, Dundee, Scotland, DD2 5DA, UK=0D=0AT: +44 (0)1382 562731 x2405 F= : +44 (0)1382 568578=0D=0AE: lp...@sc... W: http://bioinf.scri= =2Esari.ac.uk/lp=0D=0AGPG/PGP: FEFC205C E58BA41B http://www.keyserver.net = =20=0D=0A(If the signature does not verify, please remove the SC= RI disclaimer)=0D=0A_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _= _ _ _ _ _ _ _ _ _ _=0D=0A=0D=0ADISCLAIMER:=0D=0A=0D=0AThis email is from t= he Scottish Crop Research Institute, but the views=20=0D=0Aexpressed by the= sender are not necessarily the views of SCRI and its=20=0D=0Asubsidiaries.= This email and any files transmitted with it are confidential=20=0D=0Ato = the intended recipient at the e-mail address to which it has been=20=0D=0Aa= ddressed. It may not be disclosed or used by any other than that addressee= =2E=0D=0AIf you are not the intended recipient you are requested to preserv= e this=20=0D=0Aconfidentiality and you must not use, disclose, copy, print = or rely on this=20=0D=0Ae-mail in any way. Please notify pos...@sc...= ri.ac.uk quoting the=20=0D=0Aname of the sender and delete the email from y= our system.=0D=0A=0D=0AAlthough SCRI has taken reasonable precautions to en= sure no viruses are=20=0D=0Apresent in this email, neither the Institute no= r the sender accepts any=20=0D=0Aresponsibility for any viruses, and it is = your responsibility to scan the email=20=0D=0Aand the attachments (if any).=0D= =0A |
From: Matt N. <new...@ca...> - 2005-03-23 17:04:45
Attachments:
mpl_wx01.py
|
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() |