how to define a colormap dynamically

I would like to be able to define a new colormap dynamically, that
is without altering code in cm.py. It would not appear to be too
difficult to some one who knew what they were doing. I have made
some attempts following the code in cm.py and other places, but I do
not seem to be able to get the normalization correct.

Do you mean that you're having trouble with the
LinearSegmentedColormap function? I've had to do the same thing, and
I've included below my code to generate two colormaps, one is the same
as "hot" but reversed, and the other fades from read to blue. The
form seems to be:

data = {'red': ((0,r0,r0), (i1, r1, r1), (i2, r2, r2), ... (1, rn, rn)),
        'green': ... similar, 'blue': ... similar}

colormap = pylab.cm.colors.LinearSegmentedColormap('colormap',
                                               data,
                                               pylab.rcParams['image.lut'])

where i1, i2... are independent variable values from zero to 1, and
r1, r2... are red values from zero to one associated with that
variable value. Each red value appears twice to allow for
discontinuous functions, but I haen't had to use that.

I know that I could just put the data into cm.py but I would rather
not have to remember to alter this code for every release of
matplotlib and I am sure most people do not want my colormaps.

One of the things I like about python is that you can stuff things
into other namespaces without altering the original code. This is
probably not recommended and will break things, etc, but I use it to
add functionality that I consider to be missing from the software I
use. This allows me to forget whether the function is my own
extension to the package or a "native" function in the package.

Ie, I'm sure that you don't want to be typing things like:

subplot(211); pcolor(data_1,cmap=cm.hot)
subplot(212); pcolor(data_2,cmap=mycoolcolormaps.map)

because then you'll have to remember which colormaps are in which
place. So you could do something similar to this:

# Add some stuff to the scipy namespace
def lrange(l, h, dex):
    """Log-spaced array"""
    return 10**scipy.arange(scipy.log10(l), scipy.log10(h), dex)
scipy.lrange = lrange

I have used GMT (Generic Mapping Tools) extensively in the past and
have code to translate the GMT color map into a form usable by
matplotlib.

I don't have anything to offer, but I'd like more colormaps, too, so
I'm interested in whatever comes out of this discussion...

Greg

···

* James Boyle <boyle5@...99...> wrote:

Greg,
Thanks for the help. Sometimes it just takes a bit of hand holding to get things right.
I was trying the sequence of steps you indicated, but I was making a stupid mistake in the
data specification dictionary and mis-interpreted the subsequent error.
Your comment made me look harder at the details and all worked fine.

FWIW I have enclosed code to make a matplotlib color map data dictionary from a GMT
.cpt file. As I indicated previously these colormaps are found at: http://craik.shef.ac.uk/cpt-city/
there are well over a hundred from which to choose.
The code is only lightly used and not very elegant.

So if you download, for example, the 'spectrum-light.cpt' file from http://craik.shef.ac.uk/cpt-city/views/hueshift.html
then run;
cdict = gmtcolormapPylab.gmtcolormapPylab('spectrum-light')
colormap = pylab.cm.colors.LinearSegmentedColormap('spectrum-light'',cdict,pylab.rcParams['image.lut'])
pylab.contourf(XX,YY,ZZ,cmap=colormap)

you will get filled contours with the indicated colorTable.

Thanks again.

--Jim

def gmtcolormapPylab(fileName,GMTPath = None):
     import colorsys
     import Numeric
     N = Numeric
     if type(GMTPath) == type(None):
         filePath = '/Volumes/IBM1/gmt4/GMT4.0b/share/cpt/'+ fileName +'.cpt'
     else:
         filePath = GMTPath+'/'+ fileName +'.cpt'
     try:
         f = open(filePath)
     except:
         print 'file ',filePath, 'not found'
         return None

     lines = f.readlines()
     f.close()

     x =
     r =
     g =
     b =
     colorModel = 'RGB'
     for l in lines:
         ls = l.split()
         if l[0] == '#':
            if ls[-1] == 'HSV':
                colorModel = 'HSV'
                continue
            else:
                continue
         if ls[0] == 'B' or ls[0] == 'F' or ls[0] == 'N':
            pass
         else:
             x.append(float(ls[0]))
             r.append(float(ls[1]))
             g.append(float(ls[2]))
             b.append(float(ls[3]))
             xtemp = float(ls[4])
             rtemp = float(ls[5])
             gtemp = float(ls[6])
             btemp = float(ls[7])

     x.append(xtemp)
     r.append(rtemp)
     g.append(gtemp)
     b.append(btemp)

     nTable = len(r)
     x = N.array( x , N.Float)
     r = N.array( r , N.Float)
     g = N.array( g , N.Float)
     b = N.array( b , N.Float)
     if colorModel == 'HSV':
        for i in range(r.shape[0]):
            rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i])
            r[i] = rr ; g[i] = gg ; b[i] = bb
     if colorModel == 'HSV':
        for i in range(r.shape[0]):
            rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i])
            r[i] = rr ; g[i] = gg ; b[i] = bb
     if colorModel == 'RGB':
         r = r/255.
         g = g/255.
         b = b/255.
     xNorm = (x - x[0])/(x[-1] - x[0])

     red =
     blue =
     green =
     for i in range(len(x)):
         red.append([xNorm[i],r[i],r[i]])
         green.append([xNorm[i],g[i],g[i]])
         blue.append([xNorm[i],b[i],b[i]])
     colorDict = {'red':red, 'green':green, 'blue':blue}
     return (colorDict)

···

On Mar 23, 2005, at 9:47 AM, Greg Novak wrote:

* James Boyle <boyle5@...99...> wrote:

I would like to be able to define a new colormap dynamically, that
is without altering code in cm.py. It would not appear to be too
difficult to some one who knew what they were doing. I have made
some attempts following the code in cm.py and other places, but I do
not seem to be able to get the normalization correct.

Do you mean that you're having trouble with the
LinearSegmentedColormap function? I've had to do the same thing, and
I've included below my code to generate two colormaps, one is the same
as "hot" but reversed, and the other fades from read to blue. The
form seems to be:

data = {'red': ((0,r0,r0), (i1, r1, r1), (i2, r2, r2), ... (1, rn, rn)),
        'green': ... similar, 'blue': ... similar}

colormap = pylab.cm.colors.LinearSegmentedColormap('colormap',
                                               data,
                                               pylab.rcParams['image.lut'])

where i1, i2... are independent variable values from zero to 1, and
r1, r2... are red values from zero to one associated with that
variable value. Each red value appears twice to allow for
discontinuous functions, but I haen't had to use that.

I know that I could just put the data into cm.py but I would rather
not have to remember to alter this code for every release of
matplotlib and I am sure most people do not want my colormaps.

One of the things I like about python is that you can stuff things
into other namespaces without altering the original code. This is
probably not recommended and will break things, etc, but I use it to
add functionality that I consider to be missing from the software I
use. This allows me to forget whether the function is my own
extension to the package or a "native" function in the package.

Ie, I'm sure that you don't want to be typing things like:

subplot(211); pcolor(data_1,cmap=cm.hot)
subplot(212); pcolor(data_2,cmap=mycoolcolormaps.map)

because then you'll have to remember which colormaps are in which
place. So you could do something similar to this:

# Add some stuff to the scipy namespace
def lrange(l, h, dex):
    """Log-spaced array"""
    return 10**scipy.arange(scipy.log10(l), scipy.log10(h), dex)
scipy.lrange = lrange

I have used GMT (Generic Mapping Tools) extensively in the past and
have code to translate the GMT color map into a form usable by
matplotlib.

I don't have anything to offer, but I'd like more colormaps, too, so
I'm interested in whatever comes out of this discussion...

Greg