Please help with wxAgg

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 :frowning: 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@...84..., 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