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@...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