9

When making scatter plots, there are many options for diverging colour maps, that emphasise data at the extrema, but no options for a converging colour map, that emphasises data near the middle of the range. Can anyone suggest one, or tell me why it's a bad idea to use one?

My use case is a scatter plot where each point represents a fit to a different data set, and colour represents the reduced chi squared of the fit. I want to emphasise values close to one, and de-emphasise bad fits.

Edit

Here's my use case in more detail. I'm measuring the performance of an algorithm designed to distinguish between real and systematic signals in time series data (in this case planet transits in Kepler data versus glitches in the data). For each simulation I have an input value, a number describing the algorithm's decision, and a reduced chi squared measuring the goodness of fit. I want to use the colour scheme to highlight the points that have reduced chi squares closest to one, and not the cases where the fit is bad.

There are many ways I could do this (e.g with point size), but I'd like to do it with colour if I can.

Fergal
  • 494
  • 3
  • 12
  • 3
    [Here's a list of them](http://matplotlib.org/users/colormaps.html) feel free to pick one you like, or [define your own](https://stackoverflow.com/questions/16834861/create-own-colormap-using-matplotlib-and-plot-color-scale) if none of those interest you. – Cory Kramer May 21 '15 at 18:07
  • 2
    That list has sequential and diverging colour maps, but no converging ones. Diverging color maps have maximum lightness in the middle, and I want minimum lightness in the middle. – Fergal May 21 '15 at 18:10
  • I don't think I've ever seen a colormap described as converging; they fall mostly into sequential, diverging, or qualitative. I would define your own. Just curious, what is the application for this type of colormap? – wflynny May 21 '15 at 18:13
  • Look up the example CoryKramer links and make your own colormap with a lot of segments in the "interesting" range. (Or, of course, do a mathematical transform that stretches out that range, plot with any colormap, and relabel the ticks to invert the transform.) – cphlewis May 21 '15 at 18:39

1 Answers1

9

An easy approach is to modify a standard colormap. There's a scipy cookbook page on how to make a colormap transformation, and using the cmap_map function from there, one can do: enter image description here enter image description here

inv = cmap_map(lambda x: 1-x, cm.PRGn)  # the "transformation" = 1-x

#  plot the original or modified for comparison
x,y=mgrid[1:2,1:10:0.1]
plt.imshow(y, cmap=cm.PRGn)
plt.title("original")
plt.figure()
plt.imshow(y, cmap=inv)
plt.title("inverted")
plt.show()
tom10
  • 67,082
  • 10
  • 127
  • 137
  • Slightly relieved to see that the answer is non-obvious. – Fergal May 21 '15 at 20:30
  • Link seems dead. I guess [this is the updated one](https://scipy-cookbook.readthedocs.io/items/Matplotlib_ColormapTransformations.html). – Lith Apr 01 '20 at 10:09
  • @Lith: thanks, and I updated the link in the asnwer. – tom10 Apr 01 '20 at 23:19
  • In Python 3.6, I'm getting a TypeError: list cannot be interpreted as an integer, at the `step_list = sum(step_dict.values(), [])` line of `cmap_map`. So I just replaced the line with an explicit sum of the elements of `step_dict.values()` with an empty list and it seems to work. – hametbacon Aug 27 '21 at 18:13