seaborn is matplotlib with the statistics built in: hand it a DataFrame and column names, and it draws the distribution or comparison you meant — with sensible defaults. This lesson covers the three plots that carry most results sections.

Step 1 — A tidy DataFrame

seaborn wants “tidy” data — one row per observation, one column per variable:

import numpy as np
import pandas as pd

rng = np.random.default_rng(7)
df = pd.DataFrame({
    "condition": np.repeat(["control", "treated"], 60),
    "response":  np.concatenate([
        rng.normal(10.0, 1.2, 60),
        rng.normal(12.4, 1.5, 60),
    ]),
})
print(df.groupby("condition")["response"].describe())

Step 2 — Compare distributions

A box plot answers “do the groups differ?”; adding the raw points keeps it honest:

import matplotlib.pyplot as plt
import seaborn as sns

sns.boxplot(data=df, x="condition", y="response", width=0.5)
sns.stripplot(data=df, x="condition", y="response",
              color="black", size=3, alpha=0.5)
plt.xlabel("")
plt.ylabel("Response")

The strip of points over the box shows the sample size and any outliers a summary shape would hide — reviewers notice.

Step 3 — Or show the full shape

When the distribution’s shape is the story, overlay histograms:

sns.histplot(data=df, x="response", hue="condition",
             element="step", stat="density", common_norm=False)
plt.xlabel("Response")

stat="density" with common_norm=False normalises each group separately, so different group sizes still compare fairly.

Step 4 — Regression with its uncertainty

For two continuous variables, regplot scatters the data and draws the fitted line with a confidence band in one call:

df2 = pd.DataFrame({"dose": np.tile(np.arange(1, 11), 6)})
df2["effect"] = 0.8 * df2["dose"] + rng.normal(0, 1.0, len(df2))

sns.regplot(data=df2, x="dose", y="effect",
            scatter_kws={"s": 12, "alpha": 0.6})
plt.xlabel("Dose")
plt.ylabel("Effect")

For the fitted numbers themselves (slope, uncertainty), pair this with the scipy lesson — regplot draws the relationship; curve_fit quotes it.

Step 5 — Export or insert

Export / Insert as usual — vector PDF or into the paper with a \label, the script saved as the figure’s source.

Tip: seaborn styles the whole figure the moment you import it. If a plot must match your matplotlib-only figures, set sns.set_theme(style="ticks") once at the top — closer to matplotlib’s look, minus the grey.