Screenshot instructions:
Windows
Mac
Red Hat Linux
Ubuntu
Click URL instructions:
Rightclick on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)
From: T J <tjhnson@gm...>  20100527 19:32:57

Hi, I am plotting with imshow() and interpolation is turned on ('gaussian'). Part of my issue is that the distribution of values is such that I need to set the over/under colors to grab the most relevant values. If I set the over color to be the "maximum" color, then the result is too dark. Conversely for the under color. I can set the over/under colors to not draw, but then I have "holes" in my image. Is it possible to incorporate interpolation? That is, I would like to set my over color to be interpolated among its neighboring cells. This seems like it would require an (more) "intelligent" colormap, so my guess is that this isn't currently supported. I'm growing more comfortable with the mpl internals and might give a stab at implementing this, but I'm not quite sure where to start. Thanks in advance. 
From: Eric Firing <efiring@ha...>  20100527 22:24:00

On 05/27/2010 09:32 AM, T J wrote: > Hi, > > I am plotting with imshow() and interpolation is turned on > ('gaussian'). Part of my issue is that the distribution of values is > such that I need to set the over/under colors to grab the most > relevant values. If I set the over color to be the "maximum" color, > then the result is too dark. Conversely for the under color. I can > set the over/under colors to not draw, but then I have "holes" in my > image. Is it possible to incorporate interpolation? That is, I would > like to set my over color to be interpolated among its neighboring > cells. This seems like it would require an (more) "intelligent" > colormap, so my guess is that this isn't currently supported. I'm > growing more comfortable with the mpl internals and might give a stab > at implementing this, but I'm not quite sure where to start. > > Thanks in advance. I'm not sure I understand the problem; could you provide a tiny example to illustrate? Eric 
From: T J <tjhnson@gm...>  20100527 23:58:40

On Thu, May 27, 2010 at 3:23 PM, Eric Firing <efiring@...> wrote: > > I'm not sure I understand the problem; could you provide a tiny example > to illustrate? > Sure, let me focus just on the interpolation and I'll leave the filtering issue out. In the script below, I plot a 3x3 array with the center element having an "over" value. In the default case, because its value is over, the colormap will assign it the maximum color. I also plot the case when the "over" color is explicitly set to the minimum color and also to white. What I want is this: The center element should be an equal mixture of the 4 elements around it. This is partially achieved with "white" (and I suppose I could pick "grey" or "black"), but I think it might be nicer if it were a pure mixture, rather than a mixture of the surrounding colors and the "over" color. The script is attached below. Sorry it is a bit long, but I needed a discrete colormap. Can we get cmap_discrete() into matplotlib?  import matplotlib.pyplot as plt import matplotlib.colors import numpy as np from scipy import interpolate #### http://www.scipy.org/Cookbook/Matplotlib/ColormapTransformations #### Can this be added to matplotlib? def cmap_discretize(cmap, N): """Return a discrete colormap from the continuous colormap cmap. cmap: colormap instance, eg. cm.jet. N: Number of colors. Example x = resize(arange(100), (5,100)) djet = cmap_discretize(cm.jet, 5) imshow(x, cmap=djet) """ cdict = cmap._segmentdata.copy() # N colors colors_i = np.linspace(0,1.,N) # N+1 indices indices = np.linspace(0,1.,N+1) for key in ('red','green','blue'): # Find the N colors D = np.array(cdict[key]) I = interpolate.interp1d(D[:,0], D[:,1]) colors = I(colors_i) # Place these colors at the correct indices. A = np.zeros((N+1,3), float) A[:,0] = indices A[1:,1] = colors A[:1,2] = colors # Create a tuple for the dictionary. L = [] for l in A: L.append(tuple(l)) cdict[key] = tuple(L) # Return colormap object. return matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024) def draw(m, cm, norm, ncolors): ax = plt.gca() ai = ax.imshow(m, cmap=cm, norm=norm, interpolation='gaussian') cb = ax.figure.colorbar(ai) cb.set_ticks(np.linspace(.5, ncolors.5, ncolors)) cb.set_ticklabels(['$%s$' % (i,) for i in np.arange(ncolors)]) return ai, cb if __name__ == '__main__': ncolors = 4 norm = plt.Normalize(vmax=ncolors) m = np.array([[0, 0, 1], [3, 10, 1], [3, 2, 2]]) for over in [None, 'min', (1,1,1,1)]: f = plt.figure() cm = cmap_discretize(plt.cm.jet, ncolors) if over == 'min': cm.set_over(cm(0.0)) elif over is not None: cm.set_over(over) ai, cb = draw(m, cm, norm, ncolors) plt.show() 
From: Eric Firing <efiring@ha...>  20100528 00:44:22

On 05/27/2010 01:58 PM, T J wrote: > On Thu, May 27, 2010 at 3:23 PM, Eric Firing<efiring@...> wrote: >> >> I'm not sure I understand the problem; could you provide a tiny example >> to illustrate? >> > > Sure, let me focus just on the interpolation and I'll leave the > filtering issue out. > > In the script below, I plot a 3x3 array with the center element having > an "over" value. In the default case, because its value is over, the > colormap will assign it the maximum color. I also plot the case when > the "over" color is explicitly set to the minimum color and also to > white. What I want is this: > > The center element should be an equal mixture of the 4 elements around it. You can't do this via any manipulation of the colormap, or any fancier colormap specificationinstead, you have to manipulate the data value. For example, you could identify the "over" values in your data, and then use 2D interpolation to replace them with the values you want. Basemap includes a 2D interpolation routine: from mpl_toolkits.basemap import interp > > This is partially achieved with "white" (and I suppose I could pick > "grey" or "black"), but I think it might be nicer if it were a pure > mixture, rather than a mixture of the surrounding colors and the > "over" color. > > The script is attached below. Sorry it is a bit long, but I needed a > discrete colormap. Can we get cmap_discrete() into matplotlib? No, because it doesn't make much sense, given the mpl paradigm in which a colormap and a norm work together. If you want 4 colors, make a colormap with 4 colors, and use a norm that maps your data to those 4 colors. For example: cm4 = get_cmap('jet', 4) cm4a = mpl.colors.ListedColormap(get_cmap('jet', 256)([20, 70, 150, 200])) You can select any discrete set of colors you want using ListedColormap. Then you can use the default Normalize, or a custom BoundaryNorm, to map data ranges to the colors. You just don't need a lookup table with 1024 entries to specify 4 colorsit doesn't gain you anything. Eric > >  > > import matplotlib.pyplot as plt > import matplotlib.colors > > import numpy as np > from scipy import interpolate > > #### http://www.scipy.org/Cookbook/Matplotlib/ColormapTransformations > #### Can this be added to matplotlib? > def cmap_discretize(cmap, N): > """Return a discrete colormap from the continuous colormap cmap. > > cmap: colormap instance, eg. cm.jet. > N: Number of colors. > > Example > x = resize(arange(100), (5,100)) > djet = cmap_discretize(cm.jet, 5) > imshow(x, cmap=djet) > """ > > cdict = cmap._segmentdata.copy() > # N colors > colors_i = np.linspace(0,1.,N) > # N+1 indices > indices = np.linspace(0,1.,N+1) > for key in ('red','green','blue'): > # Find the N colors > D = np.array(cdict[key]) > I = interpolate.interp1d(D[:,0], D[:,1]) > colors = I(colors_i) > # Place these colors at the correct indices. > A = np.zeros((N+1,3), float) > A[:,0] = indices > A[1:,1] = colors > A[:1,2] = colors > # Create a tuple for the dictionary. > L = [] > for l in A: > L.append(tuple(l)) > cdict[key] = tuple(L) > # Return colormap object. > return matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024) > > def draw(m, cm, norm, ncolors): > ax = plt.gca() > ai = ax.imshow(m, cmap=cm, norm=norm, interpolation='gaussian') > cb = ax.figure.colorbar(ai) > cb.set_ticks(np.linspace(.5, ncolors.5, ncolors)) > cb.set_ticklabels(['$%s$' % (i,) for i in np.arange(ncolors)]) > return ai, cb > > if __name__ == '__main__': > ncolors = 4 > norm = plt.Normalize(vmax=ncolors) > m = np.array([[0, 0, 1], > [3, 10, 1], > [3, 2, 2]]) > > for over in [None, 'min', (1,1,1,1)]: > f = plt.figure() > cm = cmap_discretize(plt.cm.jet, ncolors) > if over == 'min': > cm.set_over(cm(0.0)) > elif over is not None: > cm.set_over(over) > ai, cb = draw(m, cm, norm, ncolors) > > plt.show() 
From: T J <tjhnson@gm...>  20100528 08:16:11

On Thu, May 27, 2010 at 5:44 PM, Eric Firing <efiring@...> wrote: > You can't do this via any manipulation of the colormap, or any fancier > colormap specificationinstead, you have to manipulate the data value. For > example, you could identify the "over" values in your data, and then use 2D > interpolation to replace them with the values you want. > > Basemap includes a 2D interpolation routine: > > from mpl_toolkits.basemap import interp > Thanks! >> >> This is partially achieved with "white" (and I suppose I could pick >> "grey" or "black"), but I think it might be nicer if it were a pure >> mixture, rather than a mixture of the surrounding colors and the >> "over" color. >> >> The script is attached below. Sorry it is a bit long, but I needed a >> discrete colormap. Can we get cmap_discrete() into matplotlib? > > No, because it doesn't make much sense, given the mpl paradigm in which a > colormap and a norm work together. If you want 4 colors, make a colormap > with 4 colors, and use a norm that maps your data to those 4 colors. > > For example: > > cm4 = get_cmap('jet', 4) > cm4a = mpl.colors.ListedColormap(get_cmap('jet', 256)([20, 70, 150, 200])) > > You can select any discrete set of colors you want using ListedColormap. > > Then you can use the default Normalize, or a custom BoundaryNorm, to map > data ranges to the colors. You just don't need a lookup table with 1024 > entries to specify 4 colorsit doesn't gain you anything. > Wonderful. Definitely makes the cookbook entry seem unnecessary 