From: Bogdan M. <bogdanal@b.astral.ro> - 2004-07-21 18:17:13
|
Hello all, First I want to apologize for sending this message to both lists, but I couldn't decide which one is more appropriate and I would like to have an answer as soon as possible. I discovered matplotlib some while ago, but it wasn't until recently when I decided to integrate it into one of my programs, trying to replace PyPlot that doesn't have enough features for me. I downloaded and installed version 0.60.2. Your library seemed perfect, until I discovered some strange problems that prevented me from using it as this point :( Specifically, I'm reffering to the embedding_in_wx2.py example that I found in the 'examples' directory. I modified it as follows (sorry for inlining, but I don't know if the listserver accepts any attachements at all, I didn't use it before): ================================================================= #!/usr/bin/env python """ An example of how to use wx or wxagg in an application w. or 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 Cursor: def __init__(self, canvas, ax): self.canvas = canvas self.ax = ax def mouse_move(self, widget, event): height = self.ax.figure.bbox.height() x, y = event.x, height-event.y if self.ax.in_axes(x, y): # transData transforms data coords to display coords. Use # the inverse method to transform back to data coords then # update the line # the cursor position x, y = self.ax.transData.inverse_xy_tup( (x,y) ) # the view limits minx, maxx = self.ax.viewLim.intervalx().get_bounds() miny, maxy = self.ax.viewLim.intervaly().get_bounds() print 'x=%1.2f, y=%1.2f'%(x,y) class CanvasFrame(wxFrame): def __init__(self): wxFrame.__init__(self,None,-1, 'CanvasFrame',size=( 900,900 ) ) self.SetBackgroundColour(wxNamedColor("WHITE")) self.figure = Figure( ) self.axes = self.figure.add_subplot(111) t = arange(0.0,3.0,0.01) s = sin(2*pi*t) c = sin(4*pi*t) p = self.axes.fill(t,s,'b',t,c,'g') p[ 0 ].set_alpha( 0.2 ) p[ 1 ].set_alpha( 0.2 ) #p = self.axes.fill(t,s,'b') #p[ 0 ].set_alpha( 0.2 ) #p[ 1 ].set_alpha( 0.2 ) #self.axes.plot(t,c,'g') self.axes.vlines( [1.5], -1.0, 1.0 ) self.canvas = FigureCanvas(self, -1, self.figure) self.sizer = wxBoxSizer(wxVERTICAL) self.sizer.Add(self.canvas, 1, wxTOP | wxLEFT | wxEXPAND) self.SetSizer(self.sizer) self.SetAutoLayout( True ) # self.Fit() self.sizer.Fit( self ) cursor = Cursor(self.canvas, self.axes) #cursor = SnaptoCursor(canvas, ax, t, s) self.canvas.connect('motion_notify_event', cursor.mouse_move) #self.add_toolbar() # comment this out for no toolbar # Capture the paint message EVT_PAINT(self, self.OnPaint) EVT_SIZE( self, self.OnSize) def add_toolbar(self): self.toolbar = NavigationToolbar(self.canvas, True) self.toolbar.Realize() if wxPlatform == '__WXMAC__': # Mac platform (OSX 10.3, MacPython) does not seem to cope with # having a toolbar in a sizer. This work-around gets the buttons # back, but at the expense of having the toolbar at the top self.SetToolBar(self.toolbar) else: # On Windows platform, default window size is incorrect, so set # toolbar width to figure width. tw, th = self.toolbar.GetSizeTuple() fw, fh = self.canvas.GetSizeTuple() # By adding toolbar in sizer, we are able to put it at the bottom # of the frame - so appearance is closer to GTK version. # As noted above, doesn't work for Mac. self.toolbar.SetSize(wxSize(fw, th)) self.sizer.Add(self.toolbar, 0, wxLEFT | wxEXPAND) # update the axes menu on the toolbar self.toolbar.update() def OnPaint(self, event): # self.canvas.draw() print "OnPaint" # if type( event ) == type( wxEvent ): event.Skip() def OnSize( self, event ): print "OnSize" print event.GetSize() event.Skip() # event.Skip() 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() ================================================================= The example shows just fine at first, but when I try to resize the windows it crashes (note that the original example also crashed under the same conditions). By "crashes" I mean that it exits with an unhandled exception, and Windows shows that the error is in _backend_agg.pyd. It also crashes if I change the initial figure size in .matplotlibrc (when changing figure.figsize from 8, 6 to 10, 10). I tried running in with Python 2.3.2 and Python 2.3.4, with wxPython 2.4.2.4 and wxPython 2.5.1.5, but the result was the same. I inserted some debug statements in backend_wxagg.py and it seems that the crash is in 's = agg.tostring_rgb()', the program doesn't reach the line after this call. I modified the above code in a number of ways (including changing the code for OnPaint and OnSize as the documentation is not clear at all about their role and I don't know what I should do in these handlers), but I was unable to solve the problem. Note that the same example works fine with the simple WX backend, but this is no option for me, as I would really need alpha blending, and antialiasing wouldn't hurt too. Also, I need help with the initial plot size. When I create the plot it has very large margins to the parent frame. This is not convenient to me, as I'd like to have a plot that is as large as possible and margins as small as possible. Is there a way to modify these margins? Thank you for your patience in reading this e-mail and please help me if you can. I'm not subscribed to either matplotlib-users or matplotlib-devel, so please send your replies with a copy to bogdanal@b.astral.ro, or at least let me know if I need to be subscribed to the list in order to receive your answers regarding this issue. Thank you very much for your help. Bogdan Marinescu |