help on colorbar usage.

I need help for what ought to be a pretty simple task. I am a beginner
to matplotlib, and have only written a few hundred lines of python in
my life so please take it easy on me.

I want to arrange the colorbar so that a very small number of colors
are displayed rather than the "continuous shading" that most of the
example plots are using. This lets viewers of the figure unambiguously
identify precisely the range of value in the filled region.

To demonstrate the problem I have modified the contourf_demo.py
example script.

Here is how I tried to set it up.

I specify 5 contour levels. The enpoint contour levels actually
exceed the max and min values of the field. I expect 4 filled colors to
appear on the figure, and 3 red contour lines,. There should be 4 colors
on the colorbar. The endpoint of the range plotted on the colorbar
should be -0.2 and 0.1, with a color change every 0.1 (eg 4 colors).
No matter what I try (varying number of filled regions and varying
clim) something is wrong.

I have tried everything I can think of to force this and it isnt
working. Can some kind sole suggest the fix?

Here is the script

Thanks

Phil

···

--------------------------------------------------------
#!/usr/bin/env python
from pylab import *
import matplotlib.numerix.ma as ma
origin = 'lower'
#origin = 'upper'

delta = 0.03
x = y = arange(-3.0, 3.01, delta)
X, Y = meshgrid(x, y)
Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = Z1 - Z2
ZZ = reshape(Z,[1,len(Z)*len(Z)])
print "rangeof Z", min(min(ZZ)), max(max(ZZ))

levs = [-.2,-.1,0.,0.1,0.2];
cmap = cm.get_cmap('bone', len(levs)-1)

levels, colls = contourf(X, Y, Z, levs,
                        cmap=cmap,
                        origin=origin)
print levels
levs2, colls2 = contour(X, Y, Z, levels,
                        colors = 'r',linewidths = 2,
                        origin=origin,
                        hold='on')

cb = colorbar(tickfmt='%1.3f')
clim(levs[0],levs[-1])
#savefig('contourf_demo')
show()

Phil Rasch wrote:

I need help for what ought to be a pretty simple task. I am a beginner
to matplotlib, and have only written a few hundred lines of python in
my life so please take it easy on me.

I want to arrange the colorbar so that a very small number of colors
are displayed rather than the "continuous shading" that most of the
example plots are using. This lets viewers of the figure unambiguously
identify precisely the range of value in the filled region.

To demonstrate the problem I have modified the contourf_demo.py
example script.

Here is how I tried to set it up.

I specify 5 contour levels. The enpoint contour levels actually
exceed the max and min values of the field. I expect 4 filled colors to
appear on the figure, and 3 red contour lines,. There should be 4 colors
on the colorbar. The endpoint of the range plotted on the colorbar
should be -0.2 and 0.1, with a color change every 0.1 (eg 4 colors).
No matter what I try (varying number of filled regions and varying
clim) something is wrong.

I have tried everything I can think of to force this and it isnt
working. Can some kind sole suggest the fix?

Here is the script

Thanks

Phil
--------------------------------------------------------
#!/usr/bin/env python
from pylab import *
import matplotlib.numerix.ma as ma
origin = 'lower'
#origin = 'upper'

delta = 0.03
x = y = arange(-3.0, 3.01, delta)
X, Y = meshgrid(x, y)
Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = Z1 - Z2
ZZ = reshape(Z,[1,len(Z)*len(Z)])
print "rangeof Z", min(min(ZZ)), max(max(ZZ))

levs = [-.2,-.1,0.,0.1,0.2];
cmap = cm.get_cmap('bone', len(levs)-1)

levels, colls = contourf(X, Y, Z, levs, cmap=cmap,
                       origin=origin)
print levels
levs2, colls2 = contour(X, Y, Z, levels,
                       colors = 'r',linewidths = 2,
                       origin=origin,
                       hold='on')

cb = colorbar(tickfmt='%1.3f')
clim(levs[0],levs[-1])
#savefig('contourf_demo')
show()

Phil: I've often wanted to do this too. Here's my attempt at creating a custom colormap with 16 linear segments using LinearSegmentedColormap. The contour plot looks fine, but the colorbar looks wrong. Maybe someone on the list can see what I did wrong.

-Jeff

from numarray import *
from pylab import *

def make_colormap(cmapname,rgb):
    """create matplotlib cmap instance from list of rgb tuples (0-255)"""
    x = []; r = []; g = []; b = []
    for n,xrgb in enumerate(rgb):
        if len(xrgb) > 3: # x is specified.
            x.append(float(xrgb[0]))
            r.append(float(xrgb[1]))
            g.append(float(xrgb[2]))
            b.append(float(xrgb[3]))
        else: # assume linear range for x.
            x.append(float(n+1))
            r.append(float(xrgb[0]))
            g.append(float(xrgb[1]))
            b.append(float(xrgb[2]))
    x = array( x , Float)
    r = array( r , Float)/255.
    g = array( g , Float)/255.
    b = array( b , Float)/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]])
    cdict = {'red':red, 'green':green, 'blue':blue}
    return cm.colors.LinearSegmentedColormap(cmapname,cdict,N=len(r))

def func3(x,y):
    return (1- x/2 + x**5 + y**3)*exp(-x**2-y**2)

if __name__ == '__main__':
    dx, dy = 0.05, 0.05
    x = arange(-3.0, 3.0001, dx)
    y = arange(-3.0, 3.0001, dy)
    X,Y = meshgrid(x, y)
    Z = func3(X, Y)
    Z = Z - min(ravel(Z))
    Z = Z - 0.5*max(ravel(Z))
    # Green to Magenta in 16 steps from
    # http://geography.uoregon.edu/datagraphics/color_scales.htm
    rgb = [
    ( 0, 80, 0),
    ( 0, 134, 0),
    ( 0, 187, 0),
    ( 0, 241, 0),
    ( 80, 255, 80),
    (134, 255, 134),
    (187, 255, 187),
    (255, 255, 255),
    (255, 241, 255),
    (255, 187, 255),
    (255, 134, 255),
    (255, 80, 255),
    (241, 0, 241),
    (187, 0, 187),
    (134, 0, 134),
    ( 80, 0, 80)]
    cmapname = 'GrMg_16'
    colormap = make_colormap(cmapname,rgb)
    l,c = contour (X, Y, Z, 15, linewidths=0.5,colors='k')
    l,c = contourf(X, Y, Z, 15, cmap=colormap,colors=None)
    colorbar() # segments on colorbar are not linear?
    title(cmapname)
    axis([-3,3,-3,3])
    show()

···

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/CDC R/CDC1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-124
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg