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.

Hi Bogdan,

Either list is appropriate for this kind of post. I think the users
is slightly better because then other users who may have seen the
error will get the benefit of the post and response. cross-posting
will not speed up the response, but may delay it :slight_smile:

    > 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):

Thanks for your example. I was able to trace the segfault (exposed on
win32 but not linux in my tests) to agg.tostring_rgb, as you noted.
On window maximizing, there was an uncaught memory allocation error
because I was allocating on the stack rather than the heap. This is
fixed, and your (modified) example now runs fine for me on win32.

I've built a snapshot of matplotlib-0.61 for you and uploaded it to

  http://nitace.bsd.uchicago.edu:8080/files/share/matplotlib-0.61.0a.win32-py2.3.exe

You'll notice a few changes: a new navigation toolbar - see
http://sourceforge.net/mailarchive/forum.php?thread_id=5173059&forum_id=36187
for a discussion of the new icons, what they do, and how to get the
old toolbar if you want it. As before, you can also just comment out
the set_toolbar line to remove the toolbar completely.

Also, the event handling mechanism has been changed as part of the
process of making this more generic and useful. You now call
mpl_connect rather than connect and your callback takes a single
argument. For example, if you want to know where the user clicks a
mouse on your figure, you define a function

def click(event):
    print 'you clicked', event.x, event.y

and register this function with the event handler

canvas.mpl_connect('button_press_event', click)

Then whenever the user clicks anywhere on the figure canvas, your
function will be called and passed a
matplotlib.backend_bases.MplEvent instance. The event instance has
the following attributes defined.

    name # the event name
    canvas # the FigureCanvas instance generating the event
    x # x position - pixels from left of canvas
    y # y position - pixels from bottom of canvas
    button # button pressed None, 1, 2, 3
    inaxes # the Axes instance if mouse us over axes
    xdata # x coord of mouse in data coords
    ydata # y coord of mouse in data coords

You can currently connect to the following events:
'button_press_event', button_release_event', 'motion_notify_event' and
I plan to add key press.

Below is your example, modified to work with 0.61. I fixed the event
handling and took out the onpaint connection from init (this did some
funky things in my win32 tests)

Let me know how it goes: you're the first 0.61 crash test dummy.
Anyone else who wants to try this please feel free - the new toolbar
only works with GTK* and WX* in this snapshot.

#!/usr/bin/env python
"""
An example of how to use wx or wxagg in an application w. or w/o the toolbar
"""

import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
from matplotlib.numerix import arange, sin, pi

from wxPython.wx import *

class Cursor:
    def __init__(self, canvas, ax):
        self.canvas = canvas
        self.ax = ax

    def mouse_move(self, event):
        x, y = event.x, event.y

        if event.inaxes:
            ax = event.inaxes
            minx, maxx = ax.get_xlim()
            miny, maxy = ax.get_ylim()
            print 'x=%1.2f, y=%1.2f'%(event.xdata, event.ydata)

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.sizer.Fit( self )
        
        cursor = Cursor(self.canvas, self.axes)
        #cursor = SnaptoCursor(canvas, ax, t, s)
        self.canvas.mpl_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 = NavigationToolbar2Wx(self.canvas)
        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 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()