Heatmaps and pairwise plots

seaborn · Practical · 12 min

Correlation matrices, pivot tables and a quick look at every variable pair are standard first steps in any exploration.

sns.heatmap(matrix) takes a 2D DataFrame (or array) and uses its index and columns as axis labels. It is often fed by a pivot or a correlation matrix:

table = df.pivot_table(index="weekday", columns="hour", values="orders", aggfunc="sum")

Useful arguments:

  • annot=True, fmt=".2f" writes values in the cells (fmt="d" for integers).
  • cmap= and center=0 for diverging data so zero sits at the neutral color; vmin/vmax fix the range.
  • mask= hides cells, for example the redundant upper triangle of a correlation matrix (np.triu(np.ones_like(corr, dtype=bool))).
  • square=True, linewidths=0.5, cbar_kws={"label": "..."}.

sns.clustermap reorders rows and columns by hierarchical clustering so similar ones sit together (requires SciPy).

sns.pairplot(df, hue="species") builds a grid of every numeric column against every other: scatter plots off the diagonal and distributions on it. corner=True drops the redundant upper half, and vars=[...] restricts the columns. With many columns it gets slow and unreadable; pick the relevant few.

sns.jointplot(data=df, x=..., y=..., kind="scatter" | "hex" | "kde" | "reg") shows one pair with marginal distributions along the edges, a good choice for a single important relationship.

Example

import matplotlib
matplotlib.use("Agg")
import seaborn as sns
import pandas as pd
import numpy as np

rng = np.random.default_rng(5)
df = pd.DataFrame(rng.normal(size=(300, 4)), columns=["a", "b", "c", "d"])
df["b"] += 0.8 * df["a"]
df["d"] -= 0.5 * df["c"]
df["group"] = rng.choice(["x", "y"], 300)

corr = df.drop(columns="group").corr()
mask = np.triu(np.ones_like(corr, dtype=bool))
ax = sns.heatmap(corr, mask=mask, annot=True, fmt=".2f", cmap="vlag",
                 center=0, vmin=-1, vmax=1, square=True)
print(len(ax.texts))                     # 6: only the lower triangle annotated
ax.figure.savefig("corr.png")

g = sns.pairplot(df, hue="group", vars=["a", "b", "c"], corner=True)
print(type(g).__name__, g.axes.shape)    # PairGrid (3, 3)
g.savefig("pairs.png")

Remember

  • Feed heatmap a pivot table or correlation matrix; index and columns become labels
  • Use annot, center, vmin/vmax and mask for readable matrices
  • pairplot scans all pairs; jointplot focuses on one with marginals

Watch out for

  • Running pairplot on 30 columns: 900 panels that take minutes and show nothing readable.

Check yourself

  1. Why pass `mask=np.triu(np.ones_like(corr, dtype=bool))` to a correlation heatmap?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: seaborn.pydata.org/generated/seaborn.heatmap.html