Hi,
In fixing the recursion bug in the units support, I went through the examples in
units/ and found two broken examples (broken before I fixed the recursion bug):
1) artist_tests.py
Traceback (most recent call last):
File "artist_tests.py", line 30, in <module>
lc = collections.LineCollection(verts, axes=ax)
File
"/home/rmay/.local/lib64/python2.5/site-packages/matplotlib/collections.py", line
917, in __init__
self.set_segments(segments)
File
"/home/rmay/.local/lib64/python2.5/site-packages/matplotlib/collections.py", line
927, in set_segments
seg = np.asarray(seg, np.float_)
File "/home/rmay/.local/lib64/python2.5/site-packages/numpy/core/numeric.py",
line 230, in asarray
return array(a, dtype, copy=False, order=order)
ValueError: setting an array element with a sequence.
The collection is trying to explicitly cast to a float when creating
the array instead of doing a conversion of the unit type first. The
set_segments method should convert to float using the
ax.convert_xunits before setting the array, and register to listen for
a unit change so that if for example the axis units are changed from
inches to cm, the segments are reset. Eg in Line2D, the set_axes
method calls:
def set_axes(self, ax):
Artist.set_axes(self, ax)
if ax.xaxis is not None:
self._xcid = ax.xaxis.callbacks.connect('units', self.recache)
if ax.yaxis is not None:
self._ycid = ax.yaxis.callbacks.connect('units', self.recache)
and later "recache"::
def recache(self):
#if self.axes is None: print 'recache no axes'
#else: print 'recache units', self.axes.xaxis.units,
self.axes.yaxis.units
if ma.isMaskedArray(self._xorig) or ma.isMaskedArray(self._yorig):
x = ma.asarray(self.convert_xunits(self._xorig), float)
y = ma.asarray(self.convert_yunits(self._yorig), float)
x = ma.ravel(x)
y = ma.ravel(y)
So the artist has to keep track of the original units data, and the
converted value. For simple "unit" types like datetime, this is not
so important because you convert once and you are done. For true
unitized types like basic_unit where we can switch the axis from
inches to cm, someone has to track the original unit data to convert
it to floats on a unit change. In a prior thread, I indicated I
thought the current implementation needs a rethinking, because it may
be easier for everyone concerned if the original data storage and
conversion happens at a higher layer, eg the hypothetical PlotItem
layer. As Eric pointed out, this would have the added benefit of
significantly thinning out the axes.py module code.
2) bar_unit_demo.py
Traceback (most recent call last):
File "bar_unit_demo.py", line 15, in <module>
p1 = ax.bar(ind, menMeans, width, color='r', bottom=0*cm, yerr=menStd)
File "/home/rmay/.local/lib64/python2.5/site-packages/matplotlib/axes.py", line
4134, in bar
fmt=None, ecolor=ecolor, capsize=capsize)
File "/home/rmay/.local/lib64/python2.5/site-packages/matplotlib/axes.py", line
4678, in errorbar
in cbook.safezip(y,yerr)]
TypeError: unsupported operand type(s) for -: 'int' and 'TaggedValue'
If anyone has any quick ideas on what might have gone wrong (or if these are just
outdated), let me know. Otherwise, I'll start digging...
The code is trying to add a non-unitized quantity (eg an errorbar
width but just guessing) of int type with a unitized quantity
TaggedValue (this is from the mockup basic_units testing package).
You'd have to dig a little bit to find out where the non-unitized
quantity is entering. errorbar is a complex example that was once
(and I think still is) working on the 91 branch. You may want to
compare the errorbar function on the branch vs the trunk and see what
new feature and code change broke the units support. Again, it might
be cleaner to have an ErrorbarItem that stores the errorbar function
inputs and updates artist primitives on unit change rather than try
and propagate the original unitized data down to the artist layer. As
Eric suggested, doing these one at a time is probably a good idea, and
errorbar is a good test case because it is so damned hairy
JDH
···
On Fri, Jan 16, 2009 at 2:02 PM, Ryan May <rmay31@...149...> wrote: