0

Using Python and matplotlib, is there a convenient way to do the following:

  1. Establish a mapping between colors and values, say -5 = black, -2 = red, 0 = white, +2 = blue, +5 = black

  2. Generate a colormap that interpolates between those values, similar to matplotlib.colors.LinearSegmentedColormap.from_list()

  3. Make a pseudocolor plot pcolormesh(X,Y,Z), where 0 < Z < 3 using the color coding established above. This means only a subset of the colormap will be used. (The color red will never be used since there are no negative values.)

  4. Add a colorbar ranging from 0 to 3.

This will allow to keep the mapping between values and colors consistent across multiple plots.

Jan
  • 723
  • 1
  • 11
  • 24
  • I think you can do this with `LinearSegmentedColormap` and proper limits on your normalization function. Color maps take an argument in `[0, 1]`, so your just need to map your values onto that range as you desire. – tacaswell May 29 '13 at 23:22
  • http://stackoverflow.com/questions/16834861/create-own-colormap-using-matplotlib-and-plot-color-scale – tacaswell May 30 '13 at 14:11
  • This is a duplicate of http://stackoverflow.com/questions/18926031/how-to-extract-a-subset-of-a-colormap-as-a-new-colormap-in-matplotlib. The answer there is quite good. – MattZ Jun 14 '16 at 16:48

1 Answers1

0

You need to make a custom colormap for a LinearSegmentedColormap. The explanation for how the colormap dictionary below can be understood is given in the LinearSegmentedColormap docs:

# Create the desired color dictionary
cdict = { 'red'   : ((0.0, 0.0, 0.0),
                     (0.3, 1.0, 1.0), 
                     (0.5, 1.0, 1.0),
                     (0.7, 0.0, 0.0),
                     (1.0, 0.0, 0.0)),
          'green' : ((0.0, 0.0, 0.0),
                     (0.3, 0.0, 0.0),
                     (0.5, 1.0, 1.0),
                     (0.7, 0.0, 0.0),
                     (1.0, 0.0, 0.0)),
          'blue'  : ((0.0, 0.0, 0.0),
                     (0.3, 0.0, 0.0),
                     (0.5, 1.0, 1.0),
                     (0.7, 1.0, 1.0),
                     (1.0, 0.0, 0.0)),
        }

# Create a colormap from the above dictionary
cmap = LinearSegmentedColormap('CustomColormap', cdict, 1024)
# Use the colormap in your plot
contour = pcolormesh(X,Y,Z,cmap=cmap)
# Supply the contour to the colorbar
colorbar(contour)

Basically, the colormapping can only exist from 0-1, so for color changes to happen at -5, -2, 0, 2 and 5 you would need the points to be at 0 (-5), 0.3 (-2), 0.5 (0), 0.7 (2), and 1 (5).

To get the effect you want, you will need to make sure you plot over the range -5 to 5, but then set the colorbar to only show from 0 to 3.

SethMMorton
  • 45,752
  • 12
  • 65
  • 86
  • what do you mean by 'To get the effect you want, you will need to make sure you plot over the range -5 to 5, but then set the colorbar to only show from 0 to 3.'? – tacaswell May 30 '13 at 14:14
  • If you want this color scheme to range over -5 to +5, you need tell it plot over that range. However, if you only want the colorbar to go from 0 to 3, you will have to set the colorbar scale independently from the scale that the data is plotted over. I'm sorry if I'm not being clear. I'd show some code, but I'm not sure how to do that part of what you want. – SethMMorton May 30 '13 at 16:17
  • http://stackoverflow.com/questions/16695275/set-limits-on-a-matplotlib-colorbar-without-changing-the-actual-plot/16697193#16697193 I ask because I also could not come up with a clean way to do that. – tacaswell May 30 '13 at 16:20
  • That might work. I'm not sure that matplotlib was designed to allow you to do this which make this difficult. – SethMMorton May 30 '13 at 16:27