Skip to main content
v2026.11,858 entries · CC-BY 4.0

Heatmap in Seaborn: sns.heatmap() Step by Step

Draw a heatmap in seaborn with sns.heatmap(): annotate cells, centre the colour scale, mask half a correlation matrix and read the result correctly.

Written and maintained by CASRAI Editorial Board

Last updated

A heatmap in seaborn is drawn with seaborn.heatmap(): you pass a rectangular dataset (a pandas DataFrame or a 2-D array) and each cell is coloured by its value. The function is axes-level, returns the matplotlib Axes it drew on, and is most often used to show a correlation matrix. The settings that decide whether the figure can be read correctly are annot, fmt, center, vmin/vmax and mask, and this guide walks through them in that order. The same function is what people mean when they search “seaborn heatmap” or “heatmap seaborn”.

What a seaborn heatmap is used for in research

Researchers use a heatmap to see a whole table of numbers at once: pairwise correlations between variables, a confusion matrix, or a grid of measurements across conditions. In seaborn’s own gallery the standard example is a lower-triangle correlation heatmap of many pairwise correlations. The function accepts rectangular data, writes values into the cells when asked, and puts a colour bar beside the grid by default (cbar=True).

If your goal is the statistics behind the colours, start with the CASRAI guides on the formula for correlation analysis and how to calculate Spearman correlation. For colour choices outside heatmaps see seaborn colour palettes. The same chart in R is covered in heatmap in R.

Install or access seaborn

Seaborn is installed from the Python Package Index with pip install seaborn. According to the official installation page, it requires Python 3.8 or newer and the mandatory dependencies numpy, pandas and matplotlib. SciPy is optional but is needed “for clustering matrices and some advanced options”, which matters if you later move from heatmap to clustermap.

pip install seaborn

Step by step: draw a heatmap in seaborn

1. Know the signature

The documented signature (seaborn 0.13.2) is:

seaborn.heatmap(data, *, vmin=None, vmax=None, cmap=None, center=None, robust=False, annot=None, fmt='.2g', annot_kws=None, linewidths=0, linecolor='white', cbar=True, cbar_kws=None, cbar_ax=None, square=False, xticklabels='auto', yticklabels='auto', mask=None, ax=None, **kwargs)

Extra keyword arguments are passed to matplotlib’s pcolormesh. The function returns the Axes object that holds the heatmap, and it draws on the current Axes unless you pass ax.

2. Build the matrix and draw the basic heatmap

For a correlation heatmap, compute the matrix with pandas and pass it in. numeric_only=True is needed when the DataFrame has non-numeric columns, because the pandas default is numeric_only=False.

  1. import seaborn as sns and import matplotlib.pyplot as plt
  2. corr = df.corr(numeric_only=True) where df is your DataFrame
  3. sns.heatmap(corr)
  4. plt.show()

3. Write the values in the cells (annot and fmt)

Setting annot=True writes the data value in each cell. The number format is controlled by fmt, which defaults to '.2g'; use fmt='.2f' for two decimals. You can also pass an array-like of the same shape as data to annot to print different text from the values that set the colours.

sns.heatmap(corr, annot=True, fmt='.2f')

4. Fix the colour scale (center, vmin, vmax)

vmin and vmax anchor the colormap; if you leave them out, they are inferred from the data and the other keyword arguments. For correlations, which run from -1 to 1, set both limits and set center=0 so zero sits at the neutral middle of a diverging colormap. Setting center also changes the default cmap. Setting the same limits on every figure in a paper means the same colour always stands for the same correlation.

cmap = sns.diverging_palette(230, 20, as_cmap=True)
sns.heatmap(corr, annot=True, fmt='.2f', cmap=cmap, vmin=-1, vmax=1, center=0)

robust=True uses robust quantiles instead of the extremes when vmin and vmax are not given, which stops one outlier cell from washing out the rest of the scale.

5. Hide the redundant half (mask) and square the cells

A correlation matrix is symmetric, so half of it repeats the other half. The official seaborn gallery example masks the upper triangle: mask hides cells where the mask is True, and square=True sets the Axes aspect to equal so each cell is square.

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

corr = df.corr(numeric_only=True)
mask = np.triu(np.ones_like(corr, dtype=bool))
f, ax = plt.subplots(figsize=(11, 9))
cmap = sns.diverging_palette(230, 20, as_cmap=True)
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})

This is the gallery’s “many pairwise correlations” recipe; it uses vmax=.3 because that dataset’s correlations are small. For general reporting use vmin=-1, vmax=1 as in step 4.

Output and how to read it

  • Colour bar: the bar beside the grid is the only key to what each colour means, which is why fixing vmin, vmax and center matters.
  • Blank cells are missing, not zero. Seaborn automatically masks cells with missing values. Masked cells (from mask) are blank as well, so a blank cell can mean either a mask you set or a NaN.
  • What a correlation cell contains. DataFrame.corr(method='pearson', min_periods=1, numeric_only=False) supports Pearson, Kendall and Spearman. Pearson, Kendall and Spearman are computed using pairwise complete observations, and a pair with fewer than min_periods valid pairs gives NaN. Different cells can therefore rest on different numbers of rows.
  • For a paper: state the method (pearson, spearman or kendall), how missing values were handled, and the colour limits used. Those three details are what let a reader reproduce the figure. If strong correlations between predictors appear, see perfect multicollinearity.

Troubleshooting

The heatmap has blank cells

Either the cell was masked with mask, or the value is missing. Check corr.isna(); with min_periods set, pairs with too few valid observations become NaN.

corr() raises an error about non-numeric columns

The pandas default is numeric_only=False (changed in pandas 2.0.0), so a DataFrame with text columns raises an error. Pass numeric_only=True or select the numeric columns first.

The colours look wrong or inconsistent between figures

Without vmin/vmax the scale is inferred from each dataset. Set them explicitly and add center for diverging data.

The numbers in the cells are cut or too long

Set fmt (for example '.2f'). The default '.2g' uses two significant digits.

The cells are not square

Pass square=True. The default is False.

I want the rows and columns reordered by similarity

heatmap draws the data in the order given. The seaborn documentation points to clustermap for clustered heatmaps; it relies on SciPy.

Free alternatives

Option What it does Source
seaborn.clustermap Heatmap with clustering of rows and columns; listed as the “see also” for heatmap. SciPy is needed for clustering matrices. seaborn.pydata.org
matplotlib pcolormesh The matplotlib function that receives the extra keyword arguments you pass to sns.heatmap. seaborn.pydata.org
Heatmap in R The same type of chart in R; see the CASRAI guide heatmap in R. CASRAI

FAQ

Is “heatmap seaborn” different from “seaborn heatmap”?

No. Both refer to seaborn.heatmap(), called as sns.heatmap() after import seaborn as sns.

How do I show the numbers in each cell?

Use annot=True, and set fmt to control the number format.

How do I show only half of a correlation heatmap?

Build a boolean array with np.triu(np.ones_like(corr, dtype=bool)) and pass it as mask, as in the official gallery example.

What does center do?

It sets the data value at which the colormap is centred, for divergent data, and it changes the default cmap.

Does seaborn need SciPy for a heatmap?

The installation page lists SciPy as optional, needed for clustering matrices and some advanced options. The mandatory dependencies are numpy, pandas and matplotlib.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Heatmap in Seaborn: sns.heatmap() Step by Step

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.