On Fri, Jan 16, 2009 at 2:02 PM, Ryan May <rma...@gmail.com> wrote:
> 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

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to