I am making a heatmap in seaborn. I am using 'viridis', but I modify it slightly so some of the values get particular colors. In my MWE, .set_over is used to set the values above 90 to 'black', and .set_under is used to set the values below 10 to 'white'. I also mask out part of the heatmap. This all works fine.
How can I also map a middle range value, 20, to 'orange', and without effecting the current colorbar appearance? As you can see, .set_over, and .set_under do not change the colorbar appearance.
import matplotlib
import seaborn as sns
import numpy as np
np.random.seed(7)
A = np.random.randint(0,100, size=(20,20))
mask_array = np.zeros((20, 20), dtype=bool)
mask_array[:, :5] = True
cmap = matplotlib.colormaps["viridis"]
# Set the under color to white
cmap.set_under("white")
# Set the voer color to white
cmap.set_over("black")
# Set the background color
g = sns.heatmap(A, vmin=10, vmax=90, cmap=cmap, mask=mask_array)
# Set color of masked region
g.set_facecolor('lightgrey')

I have seen Map value to specific color in seaborn heatmap, but I am not sure how I can use it to solve my problem.
Consider the following:
import matplotlib as mpl
import seaborn as sns
import numpy as np
A = np.random.randint(0,100, size=(20,20))
mask_array = np.zeros((20, 20), dtype=bool)
mask_array[:, :5] = True
cmap = mpl.colormaps["viridis"]
newcolors = cmap(np.linspace(0, 1, 100))
newcolors[:10] = np.array([1,1,1,1])
newcolors[90:] = np.array([0,0,0,1])
newcolors[20] = mpl.colors.to_rgb('tab:orange') + (1,)
newcmap = mpl.colors.ListedColormap(newcolors)
g = sns.heatmap(A, cmap=newcmap, mask=mask_array)
# Set color of masked region
g.set_facecolor('lightgrey')
Sample result:

The following (appended to the above script) will make it so that the colorbar has a visible outline.
cbar_ax = g.figure.axes[-1]
for spine in cbar_ax.spines.values():
spine.set(visible=True)
Sample result with outline:

In order to mask the colors of the heatmap, but not show an updated colorbar, set cbar=False, and then attach a custom colorbar, as shown in Standalone colorbar.
g = sns.heatmap(A, cmap=newcmap, mask=mask_array, cbar=False)
# add a new axes of the desired shape
cb = g.figure.add_axes([0.93, 0.11, 0.025, 0.77])
# attach a new colorbar to the axes
mpl.colorbar.ColorbarBase(cb, cmap='viridis', norm=mpl.colors.Normalize(10, 90), # vmax and vmin
label=None, ticks=range(10, 91, 10))

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With