Search code examples
pythonpandasseabornheatmapcolorbar

seaborn heatmap does not give the correct colors according to the cbar


I have the following dataframe:

>>>   control1    control2   control3
trt1  0.01         NaN        NaN
trt2  NaN          0.01       NaN
trt3  NaN          NaN        0.01

I have created a heatmap and defined that if values that are 0.01 and lower should be red. The problem is that they get the "p<.05" color:

ax= sns.heatmap(df, cmap=cmap,square=True,  linewidths=.3,linecolor="grey",cbar_kws={"shrink": .5})
colorbar = ax.collections[0].colorbar
colorbar.set_ticks([0.011,0.01])
colorbar.set_ticklabels(['p<0.05', 'p<0.01'])

enter image description here

I have tried also to change the values in my original df instead of 0.01 to 0.001 but it still colored it in as "salmon" and not the red:tab.

My endgoal is to get the correct color as the cbar displays.


Solution

  • This is because the min and the max values are the same in your dataframe df. So the sns.heatmap() has no range to apply the colormap on and will select the color in the middel of your cmap. If you don't change in input of your dataframe, you have to slice your cmap to the wanted color. Since you only want one color, your cmap can be a list with one string like this cmap = ['red'].

    For your example ax=sns.heatmap(df, cmap=['red'], square=True, linewidths=.3) will plot this:

    one color cmap

    Update

    As a workaround, you can extend the cmap-color-list with the last value of the cmap. This should look like this cmap = ['#DE0A0A'] + cmap.

    A simple example returns:

    ax= sns.heatmap(df, cmap = ['#DE0A0A', '#DE0A0A', '#FF7C4B'], square=True,  linewidths=.3)
    

    adapted cmap