John, It looks like you are referring to bugs in the
> Colormap.__call__ method that were introduced when I added
> support for masked values out-of-bounds values. I have
> committed a change that fixes the bugs I could find there
> (as tested with examples/image_masked.py), so that the
> colormap call produces exactly the same output with scipy as
> with Numeric or numarray--the same rgba values.
> Unfortunately, although that demo now runs with all three,
> it produces different plots. It appears that somewhere else
> in the code--I'm pretty sure it is not within colors.py--the
> floating point rgba values are getting rounded or, more
> likely, truncated, when using scipy.
Hey Eric,
Thanks for taking a look at this. The only other logical place for a
problem to reside is in colors.normalize, since the pipleline is
rgba = cmap(normalize(X))
The relevant bit of code is here -- if you or anyone else sees an
obvious candidate that might cause this truncation, let me know....
class normalize:
def __init__(self, vmin=None, vmax=None, clip = True):
"""
Normalize a given value to the 0-1 range
If vmin or vmax is not given, they are taken from the input's
minimum and maximum value respectively. If clip is True and
the given value falls outside the range, the returned value
will be 0 or 1, whichever is closer. Returns 0 if vmin==vmax.
Works with scalars or arrays, including masked arrays. If clip
is True, masked values on input will be set to 1 on output; if
clip is False, the mask will be propagated to the output.
"""
self.vmin = vmin
self.vmax = vmax
self.clip = clip
def __call__(self, value):
if isinstance(value, (int, float)):
vtype = 'scalar'
val = ma.array([value])
else:
vtype = 'array'
val = ma.asarray(value)
self.autoscale(val)
vmin, vmax = self.vmin, self.vmax
if vmin > vmax:
raise ValueError("minvalue must be less than or equal to maxvalue")
elif vmin==vmax:
return 0.*value
else:
if self.clip:
val = clip(val.filled(vmax), vmin, vmax)
result = (1.0/(vmax-vmin))*(val-vmin)
if vtype == 'scalar':
result = result[0]
return result
def autoscale(self, A):
if not self.scaled():
if self.vmin is None: self.vmin = ma.minimum(A)
if self.vmax is None: self.vmax = ma.maximum(A)
def scaled(self):
'return true if vmin and vmax set'
return (self.vmin is not None and self.vmax is not None)
JDH