How to "center" the color gradient in a heatmap/contour plot

Hi again all, a question about visualization:

I’m using heatmaps (and sometimes contour plots) to visualize an oscillating function,
using commands similar to: heatmap(xArray, yArray, MatrixOfValues, color=cgrad([:red,:white,:blue])).

Now, I would like to make sure that the zero values – the nodes – of the oscillating function (as given in the MatrixOfValues) are in the center of the white range of the color gradient. (I need to do this without changing the range of the data itself.)

I always took this for granted before as being automatic, until the functions became somewhat lopsided, and non-zero values started getting mapped into the white band (with the zero value areas suddenly being shown as light blue or red), which is very confusing.

I saw some description online about passing a vector of values to specify the positions of the color transitions; but there were not enough examples showing how that works, and I couldn’t figure out to use that to solve my problem.

Thanks for any help!

How about clims=(-1.05, 1.05).*maximum(abs, data)?

That said, I’m sure clims=:symmetric wouldn’t be that hard to implement, if someone had the time.

Hi gustaphe, that worked, thank you!

I didn’t know about the clims command before.

Using +/-1.05 x max for the range actually made the colors a little faded;
using something like clims=(-0.85, 0.85).*maximum(abs, data) actually brought the colors out more (at the cost of some color saturation at the top & bottom of the range).

I guess that depends on your goal. I mostly want all my data to be within the dynamic range - or you can’t see the difference between two values beyond the end point. If the colors aren’t vibrant enough, you might want to switch color schemes.

I’d prefer the whole data to be representable too. The current color scheme (R/W/B) has been working for me. Is there any way to “stretch” the color scheme, say, to make it not exactly linear with value, but map more of the data towards the colorful ends (more of it away from the white middle)?

I can’t find it now, but it feels like I’ve seen that.

What you can do is

  • Look for a color scheme in the docs of ColorSchemes.jl that has more color towards the middle
  • cgrad([:darkblue, :blue, :white,:red,:darkred], [0.0, 0.4, 0.5, 0.6, 1.0]) or something similar.
1 Like

Aha, good idea!

I tried cgrad([:darkblue,:white,:darkred], but didn’t like the look of it.
But putting them together and using the whole cgrad([:darkblue,:blue,:white,:red,:darkred] gives me more range & ways to control the contrast using those color transition numbers, without saturating the data at the ends.
Very good!