One colorbar for seaborn heatmaps in subplot One colorbar for seaborn heatmaps in subplot python python

One colorbar for seaborn heatmaps in subplot


The cbar parameter controls whether a colorbar should be added, and the cbar_ax parameter can optionally specify the axes where the colorbar should go. So, you could do:

import seaborn as snsimport matplotlib.pyplot as pltimport pandas as pdimport numpy as npdf = pd.DataFrame(np.random.random((10,10,)))fig, axn = plt.subplots(2, 2, sharex=True, sharey=True)cbar_ax = fig.add_axes([.91, .3, .03, .4])for i, ax in enumerate(axn.flat):    sns.heatmap(df, ax=ax,                cbar=i == 0,                vmin=0, vmax=1,                cbar_ax=None if i else cbar_ax)fig.tight_layout(rect=[0, 0, .9, 1])

(You'll get a warning about tight_layout here, but it actually is correct because we placed cbar_ax explicitly. If you don't like seeing the warning, you can also call tight_layout before plotting, but it won't be as tight).


It's actually not necessary to set cbar_ax to none for the first 3 subplots. You can set cbar_ax=cbar_ax for all 4 subplots and it will just paint the colorbar in the exact same spot 4 times, which dones't affect the look at all.

This works better for those using FacetGrid, e.g. given a dataframe df:

def draw_heatmap(*args, **kwargs):    data = kwargs.pop('data')    d = data.pivot(index=args[1], columns=args[0], values=args[2])    sns.heatmap(d, **kwargs)g = sns.FacetGrid(df, col='col_name', col_wrap=2, margin_titles=True, sharey=True)cbar_ax = g.fig.add_axes([.91, .15, .03, .7])g = g.map_dataframe(draw_heatmap, 'col_col', 'index_col', 'val_col', annot=True,                     cmap='Spectral', cbar_ax=cbar_ax, cbar_kws={'label': 'color_bar_label'})