Lesson 14
Pair Plots and Joint Plots
Scan every pair of numeric columns at once with sns.pairplot, then zoom in on one pair with sns.jointplot and its histograms along both edges.
When a table has several numeric columns, you want to know which of them move together before you pick one chart. pairplot draws a scatter for every pair and a histogram of each column on the diagonal. Once a pair looks interesting, jointplot gives it one large chart with its two distributions along the edges.
Every pair at once
pairplot uses every numeric column. With week, hours, and score that is a three by three grid. Each row shares a y axis and each column an x axis, so a panel and its mirror across the diagonal show the same pair flipped.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
rng = np.random.default_rng(26)
study = pd.DataFrame({
"track": rng.choice(["Python", "Data", "Web"], 120),
"mode": rng.choice(["online", "classroom"], 120),
"week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()
g = sns.pairplot(study, height=2.2)
plt.show()
print(type(g).__name__, g.axes.shape)
print(list(study.select_dtypes("number").columns))Output:
PairGrid (3, 3)
['week', 'hours', 'score']Colour by group
hue colours every panel by a category and switches the diagonal to density curves so groups of different size can overlap. diag_kind="hist" brings back histograms.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
rng = np.random.default_rng(26)
study = pd.DataFrame({
"track": rng.choice(["Python", "Data", "Web"], 120),
"mode": rng.choice(["online", "classroom"], 120),
"week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()
sns.pairplot(study, hue="track", height=2.2, plot_kws={"s": 18, "alpha": 0.7})
plt.show()
print(study.groupby("track")[["hours", "score"]].mean().round(1))Output:
hours score
track
Data 7.0 67.2
Python 6.5 64.2
Web 6.3 63.2Choose columns and drop the mirror
vars= limits the grid to the columns you name. corner=True removes the upper triangle, which repeats the lower one, and kind="reg" adds a trend line to every scatter.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
rng = np.random.default_rng(26)
study = pd.DataFrame({
"track": rng.choice(["Python", "Data", "Web"], 120),
"mode": rng.choice(["online", "classroom"], 120),
"week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()
g = sns.pairplot(study, vars=["hours", "score"], corner=True, kind="reg", height=2.8)
plt.show()
print(g.axes[0, 1])Output:
NoneWith corner=True the hidden panels are None, which is what the print shows.
One pair up close with jointplot
jointplot draws one scatter in the middle and each column's histogram along the top and right edges. kind swaps the middle for "reg", "kde", or "hex"; hexagons count dots per area and suit crowded data.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
rng = np.random.default_rng(26)
study = pd.DataFrame({
"track": rng.choice(["Python", "Data", "Web"], 120),
"mode": rng.choice(["online", "classroom"], 120),
"week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()
g = sns.jointplot(data=study, x="hours", y="score", kind="reg", height=5)
plt.show()
print(type(g).__name__)
print(g.ax_joint.get_xlabel(), g.ax_joint.get_ylabel())Output:
JointGrid
hours scoreGroups in a joint plot
With hue, the middle becomes a coloured scatter and the edges become one density curve per group, which shows how the groups differ on each column separately and together.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
rng = np.random.default_rng(26)
study = pd.DataFrame({
"track": rng.choice(["Python", "Data", "Web"], 120),
"mode": rng.choice(["online", "classroom"], 120),
"week": rng.integers(1, 7, 120),
})
study["hours"] = (rng.uniform(1, 6, 120) + study["week"] * 0.8).round(1)
study["score"] = (35 + study["hours"] * 4.5 + rng.normal(0, 7, 120)).clip(0, 100).round()
sns.jointplot(data=study, x="hours", y="score", hue="mode", height=5)
plt.show()
print(study.groupby("mode")[["hours", "score"]].median())Output:
hours score
mode
classroom 7.20 66.0
online 6.55 65.0Key takeaways
-
pairplot draws every pair of numeric columns, histograms on the diagonal
-
hue colours every panel; vars= picks columns; corner=True drops the mirror
-
jointplot shows one pair with its distributions along the edges
-
jointplot kind="reg", "kde", or "hex" changes the middle chart
-
Previous: Regression Plots
Loading playground…
Check your understanding
Pair Plots and Joint Plots Quiz
What does pairplot draw off the diagonal?
1 / 10