wxagg and misc wx issues

I just committed a wxagg backend. Jeremy and others may want to give
it a test drive. I use fromstring / tostring methods to transfer the
image data to the wx bitmap. This has the advantage of requiring no
wx specific extension code but obviously implies a performance hit.

This is just a first pass implementation so I tried to keep the
framework as close to the current wx setup as possible, in order to
reuse as much of backend_wx as possible. I think though that the
bitmap is not necessary since I am rendering to agg. Jeremy, can we
transfer the wxImage created in FigureCanvasWXAgg.draw directly to the
DC w/o going through the bitmap?

On my system, however, the performance is quite good. Even when/if we
have an extension solution in place, it will be nice to preserve the
string methods as a fallback for those who can't compile the extension
for some reason.

There are a couple of unrelated wx issues that need attention:

  * The toolbar seems not to work on Mac OS X, either for wx or
    wxagg. Not sure why. It doesn't even showup in the window

  * I got this email this morning

···

From: Srijit Kumar Bhadra <srijit@...42...>
        Subject: Matplotlib 0.52 and wxpython 2.5.1
        To: jdhunter@...5...
        Date: Mon, 5 Apr 2004 00:21:45 -0700 (PDT)

        Hi, This is to inform you that Matplotlib 0.52 does not work
        with wxpython 2.5.1. The corresponding code is available
        below.

        It works correctly with the previous version 2.4 of wxpython.

That's all for now,
JDH

Hi,

JC Hsu reported that loglog() was broken with numarray and was raising
an exception due to an "illegal" call to __nonzero__().

from matplotlib.matlab import *
loglog(arange(2,800))

[<matplotlib.lines.Line2D instance at 0x41e0ae8c>]

show()

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_tkagg.py", line 57, in show
    manager.show()
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_tkagg.py", line 163, in show
    self.canvas.show()
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_tkagg.py", line 115, in show
    FigureCanvasAgg.draw(self)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_agg.py", line 353, in draw
    self.figure.draw(self.renderer)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/artist.py",
line 88, in draw
    self._draw(renderer, *args, **kwargs)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/figure.py",
line 89, in _draw
    for a in self.axes: a.draw(renderer)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/artist.py",
line 88, in draw
    self._draw(renderer, *args, **kwargs)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/axes.py",
line 531, in _draw
    self.xaxis.draw(renderer)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/artist.py",
line 88, in draw
    self._draw(renderer, *args, **kwargs)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/axis.py",
line 378, in _draw
    locs = self.get_ticklocs()
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/axis.py",
line 596, in get_ticklocs
    ind = nonzero(ticklocs>=10.0**vmin * ticklocs<=10.0**vmax)
  File
"/home/jmiller/work/lib/python2.3/site-packages/numarray/generic.py",
line 474, in __nonzero__
    raise RuntimeError("An array doesn't make sense as a truth value.
Use sometrue(a) or alltrue(a).")
RuntimeError: An array doesn't make sense as a truth value. Use
sometrue(a) or alltrue(a).

Confusingly, the explicit call to nonzero() is not what is causing the
numarray problem. The problem is an implicit call to
NumArray.__nonzero__() resulting from the range expression. I found I
could "fix" the numarray exception by adding parens to the range
expression:

nonzero((ticklocs >= 10.0**ymin) * (ticklocs <= 10.0**ymax))

Evaluating using the attached script, I got the impression that while
numarray was raising an exception, Numeric was giving an unintended /
wrong answer. Anyway, I wanted to get a second opinion before
committing anything since it smacks of hacking matplotlib to work around
numarray limitations.

Lastly, assuming the parens are correct, there is still a problem with
the log functions which I haven't looked at yet:

loglog(arange(2,800))

[<matplotlib.lines.Line2D instance at 0x41e0ae8c>]

show()

opened /home/jmiller/work/share/matplotlib/Vera.ttf
log iterable warning, non-positive data ignored
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_tkagg.py", line 57, in show
    manager.show()
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_tkagg.py", line 163, in show
    self.canvas.show()
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_tkagg.py", line 115, in show
    FigureCanvasAgg.draw(self)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/backends/backend_agg.py", line 353, in draw
    self.figure.draw(self.renderer)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/artist.py",
line 88, in draw
    self._draw(renderer, *args, **kwargs)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/figure.py",
line 89, in _draw
    for a in self.axes: a.draw(renderer)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/artist.py",
line 88, in draw
    self._draw(renderer, *args, **kwargs)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/axes.py",
line 541, in _draw
    line.draw(renderer)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/artist.py",
line 88, in draw
    self._draw(renderer, *args, **kwargs)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/lines.py",
line 184, in _draw
    self._lineFunc(renderer, gc, xt, yt)
  File
"/home/jmiller/work/lib/python2.3/site-packages/matplotlib/lines.py",
line 308, in _draw_solid
    renderer.draw_lines(gc, xt,yt)
ValueError: x and y must be equal length sequences

Regards,
Todd

ticklocs.py (277 Bytes)