Jojo_697
Jojo_697

Reputation: 33

Seaborn heatmap giving same color for different values for discrete cbar

I have created a heatmap using seaborn, and have used discrete colorbar by giving colors as follows:

cmap = mpl.colors.ListedColormap(plt.cm.bwr_r([0, .35, 0.45, .5, .65, .9]))
cmap.set_under((.8, .8, .8, 1.0))
cmap

which gives me: enter image description here

The code used to generate heatmap is:

fig = plt.figure(figsize= (5.5,4.5))
g = sns.heatmap(plotting_df, cmap = cmap, annot = True, annot_kws={'fontsize': '12'}, cbar_kws={'aspect': '12', 'shrink': .7})

cbar = g.collections[0].colorbar
cbar.set_ticks([-4.3, -2.9, -1.5, 0.7, 2.5, 4.2])
cbar.set_ticklabels([-5, -4, -3, 'ns', 3, 5])

plt.show()

which gives: enter image description here

The problem is that -5 and -4 seem to have the same color and -3 seems to have the color that -4 should have had. I brainstormed quite a bit but still haven't found the mistake. Any help would be appreciated.

PS:

plotting_df = pd.DataFrame([[0, 0,  0,  0,  0,  0,  0,  0,  0,  0],
[3, 0,  0,  0,  0,  0,  0,  0,  0,  0],
[0, 0,  0,  0,  0,  0,  0,  0,  0,  0],
[5, 5,  0,  0,  0,  0,  0,  0,  0,  0],
[0, 0,  -4, 0,  0,  0,  0,  0,  0,  0],
[0, 0,  0,  0,  -3, 0,  0,  0,  0,  0],
[0, 0,  3,  0,  0,  0,  0,  0,  0,  0],
[0, 0,  -5, 0,  -5, 0,  0,  0,  0,  0],
[0, 0,  -3, 0,  -3, 0,  0,  -4, 0,  0],
[0, 0,  0,  0,  0,  0,  0,  0,  0,  0]])

Upvotes: 0

Views: 251

Answers (2)

astroChance
astroChance

Reputation: 393

One mistake is that you are manually setting the colorbar tick labels and values which leads to a misleading plot. Commenting out set_ticks and set_ticklabels produces the image below. The other answer provides a solution.

enter image description here

Upvotes: 0

Jojo_697
Jojo_697

Reputation: 33

I still didn't understand the mistake in the given code, but have found a way around by using mpl.colors.BoundaryNorm(). (https://matplotlib.org/stable/tutorials/colors/colorbar_only.html#sphx-glr-tutorials-colors-colorbar-only-py)

And, I have also added value '4' in the color bar for symmetry. But the code works without it as well.

cmap = (mpl.colors.ListedColormap(plt.cm.bwr_r([0, .3, 0.45, .5, .55, .65, .9])))
bounds = [-5, -4, -3, 0, 3, 4, 5, 6]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)

fig = plt.figure(figsize= (5.5,4.5))
g = sns.heatmap(plotting_df, cmap = cmap, annot = True, cbar = True, annot_kws={'fontsize': '12'}, cbar_kws={'aspect': '12', 'shrink': .7}, norm = norm)

cbar = g.collections[0].colorbar
cbar.set_ticks([-4.5, -3.5, -1.5, 1.5, 3.5, 4.5, 5.5])
cbar.set_ticklabels([-5, -4, -3, 'ns', 3, 4, 5])
cbar.solids.set_edgecolor("k")
g.figure.axes[-1].set_ylabel('Weights', size=14)

plt.show()

enter image description here

Upvotes: 1

Related Questions