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 Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users