On 05/02/07, John Hunter <[EMAIL PROTECTED]> wrote:
On 2/5/07, Michael Lerner <[EMAIL PROTECTED]> wrote:
> Hi,
>
> I have some data where I'd like almost all of it to be plotted with a
> LinearSegmentedColormap that I've made, but I have a few special
> values that I'd like to set to specific colors (white, in this case).
> So, I made a LinearSegmentedColormap that works pretty well, but I'm
> having trouble with the rest. I found a nice-looking example at
>
> http://www.scipy.org/Cookbook/Matplotlib/Plotting_Images_with_Special_Values
>
> But, it doesn't work for me. In particular, it complains a lot about
> _lut. I'm using matplotlib 0.87.7 on an intel Mac running OS X and
> python 2.4.
On a very quick read, it appears that the sentinel map in that example
forgot to initialize the baseclass. Eg, you need
class SentinelMap(Colormap):
def __init__(self, cmap, sentinels={}):
Colormap.__init__(self) # init the base class
# boilerplate stuff - rest of init function here
See if that helps, and let us know. If you get it working, please fix
the wiki (you may have to sign up) and post your example along with
it.
Otherwise, please post a complete code example and we'll see what we can do.
JDH
>
> Can someone show me how to make a sentinel'd version of a
> LinearSegmentedColormap?
>
> Thank you,
>
> -Michael Lerner
I had the same problem that you did with the sentinels.py.
I modified the code so that it did work, and attach it here. you can
test it by running it. It only works with numpy, because it uses
fancy indexing. I'm pretty sure it's not done the fastest way.
You first make up the colormap instance for the real data, without any
sentinels.
then use the colormap instance as an argument to the sentinel
colormap. This is why it
doesn't do a Colormap.__init__(self). Not sure that's really best,
but i just followed the original method.
HTH. George Nurser.
from matplotlib.colors import Colormap, normalize
import matplotlib.numerix as nx
from matplotlib.numerix import alltrue,ma
from types import IntType, FloatType, ListType
class SentinelMap(Colormap):
def __init__(self, cmap, sentinels={}):
# boilerplate stuff
self.N = cmap.N
self.name = 'SentinelMap'
self.cmap = cmap
self.sentinels = sentinels
for rgb in sentinels.values():
if len(rgb)!=3:
raise ValueError('sentinel color must be RGB')
def __call__(self, scaledImageData, alpha=1):
# assumes the data is already normalized (ignoring sentinels)
# clip to be on the safe side
rgbaValues = self.cmap(nx.clip(scaledImageData, 0.,1.))
for sentinel,rgb in self.sentinels.items():
r,g,b = rgb
if (scaledImageData==sentinel).max():
rgbaValues[...,0] = nx.where(scaledImageData==sentinel, r, rgbaValues[...,0])
rgbaValues[...,1] = nx.where(scaledImageData==sentinel, g, rgbaValues[...,1])
rgbaValues[...,2] = nx.where(scaledImageData==sentinel, b, rgbaValues[...,2])
rgbaValues[...,3] = nx.where(scaledImageData==sentinel, alpha, rgbaValues[...,3])
return rgbaValues
class SentinelNorm(normalize):
"""
Leave the sentinel unchanged
"""
def __init__(self, ignore=[], vmin=None, vmax=None, clip = True):
self.vmin=vmin
self.vmax=vmax
self.clip = clip
print 'in init vmax=',vmax,'vmin=',vmin
if type(ignore) in [IntType, FloatType]:
self.ignore = [ignore]
else:
self.ignore = list(ignore)
self.ignore_mask=None
def __call__(self, value, clip=None):
if clip is None:
clip = self.clip
# ensure that we have a masked array val to work with
if isinstance(value, (int, float)):
vtype = 'scalar'
val = ma.array([value])
else:
vtype = 'array'
if ma.isMA(value):
val = value
else:
val = ma.asarray(value)
# create ignore_mask, val=sentinel1 | val= sentinel2..
if self.ignore is not None:
self.get_ignore_mask(val)
# find min and max over points not masked by ignore_mask or by original mask of val
self.autoscale(val)
# now do scaling
vmin, vmax = self.vmin, self.vmax
if vmin > vmax:
if False in val.mask:
raise ValueError("minvalue must be less than or equal to maxvalue")
else:
# array is completely masked. doesn't matter what values are for plot
return 0.*value
elif vmin==vmax:
return 0.*value
else:
# scale points not masked by ignore_mask or by original mask of val
scale = 1./(vmax-vmin)
result = (val-vmin)*scale
if clip:
result = nx.clip(result,0.,1.)
# set result over sentinel points to sentinel values
if self.ignore is not None:
result[self.ignore_mask]=val.data[self.ignore_mask]
if vtype == 'scalar':
result = result[0]
return result
def get_ignore_mask(self, A):
if ma.isMA(A):
A=A.data
if self.ignore is not None:
self.ignore_mask = False
for ignore in self.ignore:
self.ignore_mask |= A==ignore
def autoscale(self, A):
# self.scaled is method in base class Normalize [colors.py], is True if self.vmin,vmax already defined
if not self.scaled():
if self.ignore is not None:
if self.ignore_mask is None:
self.get_ignore_mask(A)
A = ma.masked_where(self.ignore_mask,A)
if self.vmin is None: self.vmin = A.min()
if self.vmax is None: self.vmax = A.max()
def inverse(self, value):
if not self.scaled():
raise ValueError("Not invertible until scaled")
vmin, vmax = self.vmin, self.vmax
if isinstance(value, (int, float)):
return vmin + value * (vmax - vmin)
else:
val = ma.asarray(value)
result = vmin + val * (vmax - vmin)
if self.ignore is not None:
if self.ignore_mask is None:
self.get_ignore_mask(value)
result[self.ignore_mask]=val.data[self.ignore_mask]
return result
if __name__=="__main__":
import pylab
import matplotlib.colors
n=5
# create a random array
X = nx.mlab.rand(n,n)
xmin = X.min();xmax=X.max()
print 'xmin= ',xmin,'xmax= ',xmax
print 'X before any masking\n ',X
# set color map to be overloaded
cmBase = pylab.cm.jet
# plot original array with pcolor
pylab.figure(1)
pylab.pcolor(X, cmap=cmBase, shading='flat')
pylab.colorbar()
# define the sentinels
sentinel1 = -10.0
sentinel2 = 10.0
print 'sentinel1= ',sentinel1,'sentinel2= ', sentinel2
print '\n'
# replace some data with sentinels
X[int(.1*n):int(.2*n), int(.5*n):int(.7*n)] = sentinel1
X[int(.6*n):int(.9*n), int(.2*n):int(.5*n)] = sentinel2
print 'X after sentinels inserted\n ',X
# define the colormap and norm
rgb1 = (0.,0.,0.)
rgb2 = (.3,0.3,0.3)
cmap = SentinelMap(cmBase, sentinels={sentinel1:rgb1,sentinel2:rgb2,})
norm = SentinelNorm(ignore=[sentinel1,sentinel2])
# plot with the sentinels
pylab.figure(2)
pylab.pcolor(X, cmap = cmap, norm=norm, shading='flat')
pylab.colorbar()
# make mask
mask = nx.mlab.rand(n,n) >0.5
print 'mask\n ',mask
# now mask X
X= ma.masked_where(mask,X)
print 'masked X after sentinels inserted\n ',X
print 'doubly masked X after sentinels inserted\n ',ma.asarray(X)
# define the colormap and norm
cmap = SentinelMap(cmBase, sentinels={sentinel1:rgb1,sentinel2:rgb2,})
norm = SentinelNorm(ignore=[sentinel1,sentinel2])
# plot with the sentinels AND mask
pylab.figure(3)
pylab.pcolor(X, cmap = cmap, norm=norm, shading='flat')
pylab.colorbar()
pylab.show()
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Matplotlib-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-users