Seaborn Heatmap: Move colorbar on top of the plot

2020-07-06 03:36发布

问题:

I have a basic heatmap created using the seaborn library, and want to move the colorbar from the default, vertical and on the right, to a horizontal one above the heatmap. How can I do this?

Here's some sample data and an example of the default:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

# Create data
df = pd.DataFrame(np.random.random((5,5)), columns=["a","b","c","d","e"])

# Default heatma
ax = sns.heatmap(df)
plt.show()

回答1:

Looking at the documentation we find an argument cbar_kws. This allows to specify argument passed on to matplotlib's fig.colorbar method.

cbar_kws : dict of key, value mappings, optional. Keyword arguments for fig.colorbar.

So we can use any of the possible arguments to fig.colorbar, providing a dictionary to cbar_kws.

In this case you need location="top" to place the colorbar on top. Because colorbar by default positions the colorbar using a gridspec, which then does not allow for the location to be set, we need to turn that gridspec off (use_gridspec=False).

sns.heatmap(df, cbar_kws = dict(use_gridspec=False,location="top"))

Complete example:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.random((5,5)), columns=["a","b","c","d","e"])

ax = sns.heatmap(df, cbar_kws = dict(use_gridspec=False,location="top"))

plt.show()



回答2:

You have to use axes divider to put colorbar on top of a seaborn figure. Look for the comments.

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
from mpl_toolkits.axes_grid1.colorbar import colorbar

# Create data
df = pd.DataFrame(np.random.random((5,5)), columns=["a","b","c","d","e"])

# Use axes divider to put cbar on top
# plot heatmap without colorbar
ax = sns.heatmap(df, cbar = False)
# split axes of heatmap to put colorbar
ax_divider = make_axes_locatable(ax)
# define size and padding of axes for colorbar
cax = ax_divider.append_axes('top', size = '5%', pad = '2%')
# make colorbar for heatmap. 
# Heatmap returns an axes obj but you need to get a mappable obj (get_children)
colorbar(ax.get_children()[0], cax = cax, orientation = 'horizontal')
# locate colorbar ticks
cax.xaxis.set_ticks_position('top')

plt.show()

For more info read this official example of matplotlib: https://matplotlib.org/gallery/axes_grid1/demo_colorbar_with_axes_divider.html?highlight=demo%20colorbar%20axes%20divider

Heatmap argument like sns.heatmap(df, cbar_kws = {'orientation':'horizontal'}) is useless because it put colorbar on bottom position.



回答3:

I would like to show example with subplots which allows to control size of plot to preserve square geometry of heatmap. This example is very short:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

# Create data
df = pd.DataFrame(np.random.random((5,5)), columns=["a","b","c","d","e"])

# Define two rows for subplots
fig, (cax, ax) = plt.subplots(nrows=2, figsize=(5,5.025),  gridspec_kw={"height_ratios":[0.025, 1]})

# Draw heatmap
sns.heatmap(df, ax=ax, cbar=False)

# colorbar
fig.colorbar(ax.get_children()[0], cax=cax, orientation="horizontal")

plt.show()