Black Lives Matter. Please consider donating to Black Girls Code today.

Scale colormap such that center is always zero

When I’m using a heatmap, the colormap scales to my data. That’s nice but I always want negative values bad, positive good. Is there a way to set the scaling on the colormap to accomplish this?


Here is what you can do:

Under the colorscale argument, you can basically create your own scale customized to your needs.

I like to use exactly the idea you mentioned (green positive, white zero, and red for negative.

The way it works is that it maps colors between zero (your data minimum value) and one (your data maximum value).

So you can do the following for only red and green for example

'colorscale': [[0, 'rgba(214, 39, 40, 0.85)'], 
               [1, 'rgba(6,54,21, 0.85)']],

This would basically make the lowest value red and the highest green. All values in between would mesh between red and green.

Now, let’s put white for zero.

All you need to do is find out where in the range of your data does zero fall.
Take the absolute of 0 - min(data) / (max(data) - min(data))

Let’s say your zero falls on the point 0.142, then you simply need to add the line in the middle:

'colorscale': [[0, 'rgba(214, 39, 40, 0.85)'],   
               [0.142, 'rgba(255, 255, 255, 0.85)'],  
               [1, 'rgba(6,54,21, 0.85)']],

r: red
g: green
b: blue
a: alpha value, I like using something less than 1 to have some transparency in case there are overlaps.

The lowest value would be the ‘reddest’, gradually becoming white as values approach zero, then become green.

Hope this makes sense.


This makes perfect sense. Thank you for the advice.

I was hoping there was a way to specify the scaling such that I could generalize for any colormap.

The logic I was thinking of would be something like:

scaling_factor = max(abs(min(values)), abs(max(values)))
relevant_object.set_colormap_scale(min=-scaling_factor, max=scaling_factor)

But at least I have a viable work around with your suggestion.