From: Schalkwyk, J. <Joh...@sc...> - 2004-06-29 13:42:00
|
Thank you for the help I removed the show() command from the loop. Now just calling grid(True) multiple times. On my machine I narrowed the loop to 57 and it started happening. At 50 it did not. Another way I found to trigger this problem is to remove the for loop all together. Then it just pops up the display. Now grab the window with the mouse and shake the window continuously around, forcing multiple Paint events. Eventually it triggers the assert. The application I am developing using multiple matplotlib windows in an MDI window seems to trigger this quite easily. Everytime a window is added to the MDIParent all MDIChild windows gets repainted. Something to do with the paint event. By the way Kudos for matplotlib. Amazing. I had to dig around the code and news groups to figure out how to find the user coordinates of a mouse click. Reading the code opens your eyes the wonderful design that is backend dependent. import wx import matplotlib import time matplotlib.use('WX') from matplotlib.matlab import * class App(wx.App): """Application class.""" def OnInit(self): t = arange(0.0, 2.0, 0.01) s = sin(2*pi*t) l = plot(t, s, linewidth=1.0) xlabel('time (s)') ylabel('voltage (mV)') title('About as simple as it gets, folks') legend('line', loc='upper right') for i in range(100): grid(True) return True #--------------------------------------------------------------------------- # run the app app = App() app.MainLoop() -----Original Message----- From: John Hunter [mailto:jdh...@ac...] Sent: Monday, June 28, 2004 11:17 PM To: Schalkwyk, Johan Cc: mat...@li... Subject: Re: [Matplotlib-users] Assertion triggered in wxMemory DC >>>>> "Schalkwyk," == Schalkwyk, Johan <Joh...@sc...> writes: Schalkwyk,> The code snippet below reproduces the Schalkwyk,> problem. Basically calling "show()" in a loop forces Schalkwyk,> repaint of the same window many times. After a while a Schalkwyk,> strange stack trace appears with the assertion Schalkwyk,> above. Sometimes the stack trace creates garbage all Schalkwyk,> over the screen which has to be cleared by repainting Schalkwyk,> the whole screen. You should only call show at most once per matplotlib script - for more information on show see http://matplotlib.sf.net/faq.html#SHOW. When embedding matplotlib in an application, typically you won't use show at all. When embedding matplotlib in a GUI like WX, you should use canvas.draw() to repaint the figure. See embedding_in_wx.py in the examples directory of the matplotlib src distribution of the script embedding_in_wx2.py attached with this email for an example of how to use matplotlib in a wx app. I can't promise you this will fix your problem, but will at least make your example consistent with how matplotlib is meant to be used in a wx app. If you still get a problem, please post the revised code and I'll take a look. Good luck! JDH #!/usr/bin/env python """ An example of how to use wx or wxagg in an application w/o the toolbar """ from matplotlib.numerix import arange, sin, pi import matplotlib # uncomment the following to use wx rather than wxagg #matplotlib.use('WX') #from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas # comment out the following to use wx rather than wxagg matplotlib.use('WXAgg') from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas from matplotlib.figure import Figure from wxPython.wx import * class CanvasFrame(wxFrame): def __init__(self): wxFrame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(wxNamedColor("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.axes = self.figure.add_subplot(111) t = arange(0.0,3.0,0.01) s = sin(2*pi*t) self.axes.plot(t,s) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) def OnPaint(self, event): self.canvas.draw() class App(wxApp): def OnInit(self): 'Create the main window and insert the custom frame' frame = CanvasFrame() frame.Show(true) return true app = App(0) app.MainLoop() |
From: Schalkwyk, J. <Joh...@sc...> - 2004-06-29 15:20:27
|
The example I created was the smallest sample code I could make to reproduce the problem. The code below is more true to my application. It does not use the matlab interface. It does however mimick the matlab interface. I did not have the src distribution so I created this from reading the code. Note the main frame calls the draw command on the canvas (MatlabFigure) 100 times. This triggers the problem as well. I'll take a look at the source distribution. Thank you for the help Johan import wx import matplotlib import numarray matplotlib.use('WX') from matplotlib.figure import Figure from matplotlib.backends.backend_wx import FigureCanvasWx from matplotlib.backend_bases import FigureManagerBase, error_msg from matplotlib.axes import Axes from matplotlib.cbook import flatten, is_string_like, exception_to_str import matplotlib.mlab as mlab #--------------------------------------------------------------------------- class MatlabFigure(FigureCanvasWx): def __init__(self, parent): self.fig = Figure() FigureCanvasWx.__init__(self, parent, -1, self.fig) self.figmgr = FigureManagerBase(self, 0) self.gca = self.figmgr.get_current_axis() # end def def GetXY(self, event): screenPos= numarray.array( event.GetPosition()) ymin, height = self.fig.bbox.intervaly().get_bounds() x, y = screenPos[0], height-screenPos[1] if self.gca.in_axes(x, y): xy = self.gca.transData.inverse_xy_tup((x, y)) return xy else: return None # end if # end def def axis(self, *v): if len(v)==1 and is_string_like(v[0]): s = v[0] if s.lower()=='on': self.gca.set_axis_on() elif s.lower()=='off': self.gca.set_axis_off() else: error_msg('Unrecognized string %s to axis; try on or off' % s) return # end if try: v[0] except IndexError: xlim = self.gca.get_xlim() ylim = self.gca.get_ylim() return [xlim[0], xlim[1], ylim[0], ylim[1]] # end except v = v[0] if len(v) != 4: error_msg('v must contain [xmin xmax ymin ymax]') return # end if self.gca.set_xlim([v[0], v[1]]) self.gca.set_ylim([v[2], v[3]]) # end def def axes(self, *args, **kwargs): nargs = len(args) if len(args)==0: return subplot(111, **kwargs) if nargs>1: error_msg('Only one non keyword arg to axes allowed') return # end if arg = args[0] if isinstance(arg, Axes): self.figmgr.set_current_axes(arg) ret = arg else: rect = arg ret = self.figmgr.add_axes(rect, **kwargs) # end if return ret # end def def bar(self, *args, **kwargs): try: patches = self.gca.bar(*args, **kwargs) except Exception, msg: s = exception_to_str(msg) error_msg(s) raise RuntimeError(msg) # end except return patches # end def def cla(self): self.gca.cla() # end def def clf(self): self.figmgr.clf() # end def def errorbar(self, x, y, yerr=None, xerr=None, fmt='b-', ecolor='k', capsize=3): try: ret = self.gca.errorbar(x, y, yerr, xerr, fmt, ecolor, capsize) except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) else: return ret # end try # end def def figlegend(self, handles, labels, loc): l = self.legend(handles, labels, loc) return l # end def def fill(self, *args, **kwargs): try: patch = self.gca.fill(*args, **kwargs) except Exception, msg: s = exception_to_str(msg) error_msg(s) raise RuntimeError('Could not exectute fill') # end except return patch # end def def grid(self, b): self.gca.grid(b) # end def def hist(self, x, bins=10, noplot=0, normed=0, bottom=0): if noplot: return mlab.hist(x, bins, normed) else: try: ret = self.gca.hist(x, bins, normed, bottom) except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) raise RuntimeError, msg return ret # end if # end def def legend(self, *args, **kwargs): ret = self.gca.legend(*args, **kwargs) return ret # end def def plot(self, *args, **kwargs): try: lines = self.gca.plot(*args, **kwargs) except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) return lines # end def def savefig(self, *args, **kwargs): for key in ('dpi', 'facecolor', 'edgecolor'): if not kwargs.has_key(key): kwargs[key] = rcParams['savefig.%s'%key] self.print_figure(*args, **kwargs) # end def def scatter(self, *args, **kwargs): try: patches = self.gca.scatter(*args, **kwargs) except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) raise RuntimeError, msg return patches # end def def scatter_classic(self, *args, **kwargs): try: patches = self.gca.scatter_classic(*args, **kwargs) except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) raise RuntimeError, msg return patches # end def def stem(self, *args, **kwargs): try: ret = self.gca.stem(*args, **kwargs) except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) else: return ret # end def def subplot(self, *args, **kwargs): try: self.figmgr.add_subplot(*args, **kwargs) self.gca = self.figmgr.get_current_axis() except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) raise RuntimeError, msg return self.gca # end def def text(self, x, y, label, fontdict=None, **kwargs): t = self.gca.text(x, y, label, fontdict, **kwargs) return t # end def def title(self, s, *args, **kwargs): l = self.gca.set_title(s, *args, **kwargs) return l # end def def vlines(self, *args, **kwargs): try: lines = self.gca.vlines(*args, **kwargs) except ValueError, msg: msg = raise_msg_to_str(msg) error_msg(msg) raise RuntimeError, msg return lines # end def def xlabel(self, s, *args, **kwargs): l = self.gca.set_xlabel(s, *args, **kwargs) return l # end def def ylabel(self, s, *args, **kwargs): l = self.gca.set_ylabel(s, *args, **kwargs) return l # end def #--------------------------------------------------------------------------- # class MatFrame(wx.MDIChildFrame): class MatFrame(wx.Frame): def __init__(self, parent): #wx.MDIChildFrame.__init__(self, parent, -1, "Matlab WX interface", # size=(600,600)) wx.Frame.__init__(self, None, -1, "Matlab WX interface", size=(600,600)) self.figure = figure = MatlabFigure(self) # histg = figure.hist([1,2,3,4,5,6,7,7,8,9,1,23,4,5,5,6]) histg = figure.bar([1,2,3,4], [10,15, 7, 3], width=1) line1 = figure.plot([1,2,3,4], [2,3,6,7], 'b-') line2 = figure.plot([0,10,20], [0,10,20], 'g') figure.axis([0,30,0,20]) figure.grid(1) figure.xlabel('Confidence', {'fontsize': 'small'}) figure.ylabel('Count', {'fontsize': 'small'}) figure.legend((line1, line2, histg), ('line1', 'line2', 'histg'), 'upper right') figure.title('Confidence Histogram') figure.Bind(wx.EVT_LEFT_DOWN, self.OnSelectBucket) # end def def OnSelectBucket(self, event): xy = self.figure.GetXY(event) print xy # end def #--------------------------------------------------------------------------- class MatlabMDI(wx.MDIParentFrame): def __init__(self): wx.MDIParentFrame.__init__(self, None, -1, "Matlab MDI",size=(900,700)) MatFrame(self) self.Show() # end def class App(wx.App): """Application class.""" def OnInit(self): #MatlabMDI() frame = MatFrame(self) frame.Show() for i in range(100): frame.figure.draw() # end for #self.xframe = MatFrame() #self.xframe.Show() #self.xframe.grid(0) return True # end def #--------------------------------------------------------------------------- if __name__ == '__main__': app = App() app.MainLoop() -----Original Message----- From: John Hunter [mailto:jdh...@ac...] Sent: Tuesday, June 29, 2004 10:47 AM To: Schalkwyk, Johan Cc: mat...@li... Subject: Re: [Matplotlib-users] Assertion triggered in wxMemory DC >>>>> "Schalkwyk," == Schalkwyk, Johan <Joh...@sc...> writes: Schalkwyk,> Thank you for the help I removed the show() command Schalkwyk,> from the loop. Now just calling grid(True) multiple Schalkwyk,> times. On my machine I narrowed the loop to 57 and it Schalkwyk,> started happening. At 50 it did not. Perhaps I didn't make myself clear. The way you are using matplotlib does not make sense. matplotlib has two modes: a "matlab interface" and an embedded interface. You should not embed the matlab interface directly into a GUI. The matlab interface does a lot of stuff under the hood, like creating and managing figures and figure windows, managing redraws, etc. When you create your own figure window outside this framework, and then try to use the framework, the result is undefined. If you are using matplotlib in a GUI, *do not import matplotlib.matlab*. You need to follow the example of embedding_in_wx2.py. Below is your example translated to the GUI interface - on my system, calling grid until the sun sets presents no problems, and it really couldn't because all it does is set a boolean. In the matlab interface, if you have interactive: True in your rc file, calling grid does a lot more, including repainting the figure. Try running this example, shaking it, resizing it, etc... and see if you can crash it; I was unable to cause any problems. If you have trouble, please let me know, but also consider trying replacing wx for wxagg, which uses antigrain for drawing and is probably more stable than wx, which does occasionally show dc related errors. By the way, there was an error in your legend code You had legend('line', blahblah) and you need legend( ('line',), blahblah) That is, legend expects a list or tuple of strings, not a string. Schalkwyk,> By the way Kudos for matplotlib. Amazing. I had to dig Schalkwyk,> around the code and news groups to figure out how to Schalkwyk,> find the user coordinates of a mouse click. Reading Schalkwyk,> the code opens your eyes the wonderful design that is Schalkwyk,> backend dependent. Thanks. Do you have the src distribution? There is an example in the examples directory examples/coords_demo.py (works with Tk, GTK and WX) that shows you how to get the mouse click coordinates. The examples dir is your first line of defense when you want to figure out something new. Unfortunately, I forgot to upload the zip file with the 0.54.2 release, so look here http://matplotlib.sf.net/examples Here's the example: #!/usr/bin/env python """ An example of how to use wx or wxagg in an application w/o the toolbar """ from matplotlib.numerix import arange, sin, pi import matplotlib matplotlib.use('WX') from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas from matplotlib.figure import Figure from wxPython.wx import * class CanvasFrame(wxFrame): def __init__(self): wxFrame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(wxNamedColor("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.ax = self.figure.add_subplot(111) t = arange(0.0, 2.0, 0.01) s = sin(2*pi*t) l = self.ax.plot(t, s, linewidth=1.0) self.ax.set_xlabel('time (s)') self.ax.set_ylabel('voltage (mV)') self.ax.set_title('About as simple as it gets, folks') self.ax.legend(('line',), loc='upper right') for i in range(100): self.ax.grid(True) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) def OnPaint(self, event): self.canvas.draw() class App(wxApp): def OnInit(self): 'Create the main window and insert the custom frame' frame = CanvasFrame() frame.Show(true) return true app = App(0) app.MainLoop() |
From: Schalkwyk, J. <Joh...@sc...> - 2004-06-29 15:26:14
|
With the attached example code you sent me I get the following messages after some time. It seems to be caught in some form of endless loop, just scrolling the messages over and over. Also thank you for the example. I can simply my app code much more now. Where can I find the src distribution. I probably did not look properly on the web site. Johan line 570, in new_gc self.gc = GraphicsContextWx(self.bitmap, self) File "c:\Tools\Python23\lib\site-packages\matplotlib\backends\backend_wx.py", line 682, in __init__ self.SelectObject(bitmap) File "C:\Tools\Python23\Lib\site-packages\wx\gdi.py", line 3017, in SelectObje ct return _gdi.MemoryDC_SelectObject(*args, **kwargs) wx.core.PyAssertionError: C++ assertion "wxAssertFailure" failed in ..\..\src\ms w\dcmemory.cpp(133): Couldn't select a bitmap into wxMemoryDC Traceback (most recent call last): File "mattest2.py", line 42, in OnPaint self.canvas.draw() File "c:\Tools\Python23\lib\site-packages\matplotlib\backends\backend_wx.py", line 921, in draw self.figure.draw(self.renderer) File "c:\Tools\Python23\lib\site-packages\matplotlib\figure.py", line 132, in draw if self.frameon: self._figurePatch.draw(renderer) File "C:\Tools\Python23\Lib\site-packages\matplotlib\patches.py", line 54, in draw gc = renderer.new_gc() File "c:\Tools\Python23\lib\site-packages\matplotlib\backends\backend_wx.py", line 570, in new_gc -----Original Message----- From: John Hunter [mailto:jdh...@ac...] Sent: Tuesday, June 29, 2004 10:47 AM To: Schalkwyk, Johan Cc: mat...@li... Subject: Re: [Matplotlib-users] Assertion triggered in wxMemory DC >>>>> "Schalkwyk," == Schalkwyk, Johan <Joh...@sc...> writes: Schalkwyk,> Thank you for the help I removed the show() command Schalkwyk,> from the loop. Now just calling grid(True) multiple Schalkwyk,> times. On my machine I narrowed the loop to 57 and it Schalkwyk,> started happening. At 50 it did not. Perhaps I didn't make myself clear. The way you are using matplotlib does not make sense. matplotlib has two modes: a "matlab interface" and an embedded interface. You should not embed the matlab interface directly into a GUI. The matlab interface does a lot of stuff under the hood, like creating and managing figures and figure windows, managing redraws, etc. When you create your own figure window outside this framework, and then try to use the framework, the result is undefined. If you are using matplotlib in a GUI, *do not import matplotlib.matlab*. You need to follow the example of embedding_in_wx2.py. Below is your example translated to the GUI interface - on my system, calling grid until the sun sets presents no problems, and it really couldn't because all it does is set a boolean. In the matlab interface, if you have interactive: True in your rc file, calling grid does a lot more, including repainting the figure. Try running this example, shaking it, resizing it, etc... and see if you can crash it; I was unable to cause any problems. If you have trouble, please let me know, but also consider trying replacing wx for wxagg, which uses antigrain for drawing and is probably more stable than wx, which does occasionally show dc related errors. By the way, there was an error in your legend code You had legend('line', blahblah) and you need legend( ('line',), blahblah) That is, legend expects a list or tuple of strings, not a string. Schalkwyk,> By the way Kudos for matplotlib. Amazing. I had to dig Schalkwyk,> around the code and news groups to figure out how to Schalkwyk,> find the user coordinates of a mouse click. Reading Schalkwyk,> the code opens your eyes the wonderful design that is Schalkwyk,> backend dependent. Thanks. Do you have the src distribution? There is an example in the examples directory examples/coords_demo.py (works with Tk, GTK and WX) that shows you how to get the mouse click coordinates. The examples dir is your first line of defense when you want to figure out something new. Unfortunately, I forgot to upload the zip file with the 0.54.2 release, so look here http://matplotlib.sf.net/examples Here's the example: #!/usr/bin/env python """ An example of how to use wx or wxagg in an application w/o the toolbar """ from matplotlib.numerix import arange, sin, pi import matplotlib matplotlib.use('WX') from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas from matplotlib.figure import Figure from wxPython.wx import * class CanvasFrame(wxFrame): def __init__(self): wxFrame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(wxNamedColor("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.ax = self.figure.add_subplot(111) t = arange(0.0, 2.0, 0.01) s = sin(2*pi*t) l = self.ax.plot(t, s, linewidth=1.0) self.ax.set_xlabel('time (s)') self.ax.set_ylabel('voltage (mV)') self.ax.set_title('About as simple as it gets, folks') self.ax.legend(('line',), loc='upper right') for i in range(100): self.ax.grid(True) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) def OnPaint(self, event): self.canvas.draw() class App(wxApp): def OnInit(self): 'Create the main window and insert the custom frame' frame = CanvasFrame() frame.Show(true) return true app = App(0) app.MainLoop() |
From: Schalkwyk, J. <Joh...@sc...> - 2004-06-29 15:26:38
|
Some more info. I'm running a 1.8Ghz PIV laptop with windows XP professional. Not sure if speed of machine has anything todo with it. The repaints cause flicker on the window, and then after a while the messages appear. -----Original Message----- From: Schalkwyk, Johan Sent: Tuesday, June 29, 2004 11:25 AM To: 'John Hunter'; Schalkwyk, Johan Cc: mat...@li... Subject: RE: [Matplotlib-users] Assertion triggered in wxMemory DC With the attached example code you sent me I get the following messages after some time. It seems to be caught in some form of endless loop, just scrolling the messages over and over. Also thank you for the example. I can simply my app code much more now. Where can I find the src distribution. I probably did not look properly on the web site. Johan line 570, in new_gc self.gc = GraphicsContextWx(self.bitmap, self) File "c:\Tools\Python23\lib\site-packages\matplotlib\backends\backend_wx.py", line 682, in __init__ self.SelectObject(bitmap) File "C:\Tools\Python23\Lib\site-packages\wx\gdi.py", line 3017, in SelectObje ct return _gdi.MemoryDC_SelectObject(*args, **kwargs) wx.core.PyAssertionError: C++ assertion "wxAssertFailure" failed in ..\..\src\ms w\dcmemory.cpp(133): Couldn't select a bitmap into wxMemoryDC Traceback (most recent call last): File "mattest2.py", line 42, in OnPaint self.canvas.draw() File "c:\Tools\Python23\lib\site-packages\matplotlib\backends\backend_wx.py", line 921, in draw self.figure.draw(self.renderer) File "c:\Tools\Python23\lib\site-packages\matplotlib\figure.py", line 132, in draw if self.frameon: self._figurePatch.draw(renderer) File "C:\Tools\Python23\Lib\site-packages\matplotlib\patches.py", line 54, in draw gc = renderer.new_gc() File "c:\Tools\Python23\lib\site-packages\matplotlib\backends\backend_wx.py", line 570, in new_gc -----Original Message----- From: John Hunter [mailto:jdh...@ac...] Sent: Tuesday, June 29, 2004 10:47 AM To: Schalkwyk, Johan Cc: mat...@li... Subject: Re: [Matplotlib-users] Assertion triggered in wxMemory DC >>>>> "Schalkwyk," == Schalkwyk, Johan <Joh...@sc...> writes: Schalkwyk,> Thank you for the help I removed the show() command Schalkwyk,> from the loop. Now just calling grid(True) multiple Schalkwyk,> times. On my machine I narrowed the loop to 57 and it Schalkwyk,> started happening. At 50 it did not. Perhaps I didn't make myself clear. The way you are using matplotlib does not make sense. matplotlib has two modes: a "matlab interface" and an embedded interface. You should not embed the matlab interface directly into a GUI. The matlab interface does a lot of stuff under the hood, like creating and managing figures and figure windows, managing redraws, etc. When you create your own figure window outside this framework, and then try to use the framework, the result is undefined. If you are using matplotlib in a GUI, *do not import matplotlib.matlab*. You need to follow the example of embedding_in_wx2.py. Below is your example translated to the GUI interface - on my system, calling grid until the sun sets presents no problems, and it really couldn't because all it does is set a boolean. In the matlab interface, if you have interactive: True in your rc file, calling grid does a lot more, including repainting the figure. Try running this example, shaking it, resizing it, etc... and see if you can crash it; I was unable to cause any problems. If you have trouble, please let me know, but also consider trying replacing wx for wxagg, which uses antigrain for drawing and is probably more stable than wx, which does occasionally show dc related errors. By the way, there was an error in your legend code You had legend('line', blahblah) and you need legend( ('line',), blahblah) That is, legend expects a list or tuple of strings, not a string. Schalkwyk,> By the way Kudos for matplotlib. Amazing. I had to dig Schalkwyk,> around the code and news groups to figure out how to Schalkwyk,> find the user coordinates of a mouse click. Reading Schalkwyk,> the code opens your eyes the wonderful design that is Schalkwyk,> backend dependent. Thanks. Do you have the src distribution? There is an example in the examples directory examples/coords_demo.py (works with Tk, GTK and WX) that shows you how to get the mouse click coordinates. The examples dir is your first line of defense when you want to figure out something new. Unfortunately, I forgot to upload the zip file with the 0.54.2 release, so look here http://matplotlib.sf.net/examples Here's the example: #!/usr/bin/env python """ An example of how to use wx or wxagg in an application w/o the toolbar """ from matplotlib.numerix import arange, sin, pi import matplotlib matplotlib.use('WX') from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas from matplotlib.figure import Figure from wxPython.wx import * class CanvasFrame(wxFrame): def __init__(self): wxFrame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(wxNamedColor("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.ax = self.figure.add_subplot(111) t = arange(0.0, 2.0, 0.01) s = sin(2*pi*t) l = self.ax.plot(t, s, linewidth=1.0) self.ax.set_xlabel('time (s)') self.ax.set_ylabel('voltage (mV)') self.ax.set_title('About as simple as it gets, folks') self.ax.legend(('line',), loc='upper right') for i in range(100): self.ax.grid(True) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) def OnPaint(self, event): self.canvas.draw() class App(wxApp): def OnInit(self): 'Create the main window and insert the custom frame' frame = CanvasFrame() frame.Show(true) return true app = App(0) app.MainLoop() |
From: John H. <jdh...@ac...> - 2004-06-29 15:10:57
|
>>>>> "Schalkwyk," == Schalkwyk, Johan <Joh...@sc...> writes: Schalkwyk,> Thank you for the help I removed the show() command Schalkwyk,> from the loop. Now just calling grid(True) multiple Schalkwyk,> times. On my machine I narrowed the loop to 57 and it Schalkwyk,> started happening. At 50 it did not. Perhaps I didn't make myself clear. The way you are using matplotlib does not make sense. matplotlib has two modes: a "matlab interface" and an embedded interface. You should not embed the matlab interface directly into a GUI. The matlab interface does a lot of stuff under the hood, like creating and managing figures and figure windows, managing redraws, etc. When you create your own figure window outside this framework, and then try to use the framework, the result is undefined. If you are using matplotlib in a GUI, *do not import matplotlib.matlab*. You need to follow the example of embedding_in_wx2.py. Below is your example translated to the GUI interface - on my system, calling grid until the sun sets presents no problems, and it really couldn't because all it does is set a boolean. In the matlab interface, if you have interactive: True in your rc file, calling grid does a lot more, including repainting the figure. Try running this example, shaking it, resizing it, etc... and see if you can crash it; I was unable to cause any problems. If you have trouble, please let me know, but also consider trying replacing wx for wxagg, which uses antigrain for drawing and is probably more stable than wx, which does occasionally show dc related errors. By the way, there was an error in your legend code You had legend('line', blahblah) and you need legend( ('line',), blahblah) That is, legend expects a list or tuple of strings, not a string. Schalkwyk,> By the way Kudos for matplotlib. Amazing. I had to dig Schalkwyk,> around the code and news groups to figure out how to Schalkwyk,> find the user coordinates of a mouse click. Reading Schalkwyk,> the code opens your eyes the wonderful design that is Schalkwyk,> backend dependent. Thanks. Do you have the src distribution? There is an example in the examples directory examples/coords_demo.py (works with Tk, GTK and WX) that shows you how to get the mouse click coordinates. The examples dir is your first line of defense when you want to figure out something new. Unfortunately, I forgot to upload the zip file with the 0.54.2 release, so look here http://matplotlib.sf.net/examples Here's the example: #!/usr/bin/env python """ An example of how to use wx or wxagg in an application w/o the toolbar """ from matplotlib.numerix import arange, sin, pi import matplotlib matplotlib.use('WX') from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas from matplotlib.figure import Figure from wxPython.wx import * class CanvasFrame(wxFrame): def __init__(self): wxFrame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(wxNamedColor("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.ax = self.figure.add_subplot(111) t = arange(0.0, 2.0, 0.01) s = sin(2*pi*t) l = self.ax.plot(t, s, linewidth=1.0) self.ax.set_xlabel('time (s)') self.ax.set_ylabel('voltage (mV)') self.ax.set_title('About as simple as it gets, folks') self.ax.legend(('line',), loc='upper right') for i in range(100): self.ax.grid(True) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) # Capture the paint message EVT_PAINT(self, self.OnPaint) def OnPaint(self, event): self.canvas.draw() class App(wxApp): def OnInit(self): 'Create the main window and insert the custom frame' frame = CanvasFrame() frame.Show(true) return true app = App(0) app.MainLoop() |