On 05/27/2010 01:58 PM, T J wrote:
> On Thu, May 27, 2010 at 3:23 PM, Eric Firing<efir...@hawaii.edu>  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 specification--instead, you have to manipulate the data value. 
  For example, you could identify the "over" values in your data, and 
then use 2-D interpolation to replace them with the values you want.

Basemap includes a 2-D 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 colors--it 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()


------------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to