Module 8 — Visualization with Matplotlib and Seaborn
A describe() says the mean is 48; it does not say the distribution has two humps, a gap in the middle and twelve outliers. Visualization is a diagnostic tool before it is a presentation tool: you plot to see what statistics summarize too well. This module gives the mechanics (Matplotlib), the statistical shortcuts (Seaborn) and the selection rules.
Matplotlib: figure, axes, and the explicit interface
Matplotlib has two writing styles. The plt.plot(...) style is fine for throwaway plots; as soon as a chart matters, the object-oriented style is clearer and more controllable:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(9, 5))
ax.plot(monthly_revenue.index, monthly_revenue.values, marker="o")
ax.set_title("Monthly revenue 2026")
ax.set_xlabel("Month")
ax.set_ylabel("Revenue (k$)")
ax.grid(alpha=0.3)
fig.savefig("monthly_revenue.png", dpi=150, bbox_inches="tight")
The figure is the canvas; the axes (ax) are one chart on it. This distinction pays off as soon as you compose several views:
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].hist(df["amount"], bins=40)
axes[1].boxplot(df["amount"])
Every library in the ecosystem (pandas .plot(), Seaborn) produces Matplotlib axes: knowing how to touch them up (ax.set_...) is therefore useful everywhere.
The four questions and their charts
The chart choice follows from the question asked — not from the inventory of available types.
| Question | Chart | Typical command |
|---|---|---|
| How is a variable distributed? | Histogram | ax.hist(x, bins=40) / sns.histplot |
| How does it evolve over time? | Line | ax.plot(dates, y) |
| How are two variables related? | Scatter plot | ax.scatter(x, y) / sns.scatterplot |
| How do groups compare? | Bars or boxes | ax.bar / sns.boxplot |
Two field notes. The histogram depends on the bin count: try several bins before concluding on the shape. The scatter plot saturates beyond a few tens of thousands of points: alpha=0.1 or a sample (df.sample(5000)) make the density readable.
Seaborn: the statistical layer
Seaborn speaks DataFrame natively — data=, x=, y=, hue= — and draws in one line what would take ten lines of Matplotlib:
import seaborn as sns
sns.histplot(data=df, x="amount", hue="segment", bins=40) # distributions per group
sns.boxplot(data=df, x="segment", y="amount") # group comparisons
sns.scatterplot(data=df, x="tenure", y="basket", hue="country", alpha=0.4)
sns.heatmap(df[num_cols].corr(), annot=True, cmap="coolwarm", center=0) # correlations
The hue parameter — a third variable encoded as color — is the big daily win: comparing segments within each chart without multiplying figures. The correlation heatmap is the mandatory stop of pre-model exploration: it reveals redundant variables and unexpected relationships (remembering that correlation measures linear links — a U-shaped link escapes it, one more reason to plot the scatter).
Visual honesty: four rules
A chart can lie faster than a table. The rules that keep it honest — toward others and toward yourself:
Bar axes start at zero. A bar cut at 95 turns a 2% gap into a cliff. For lines, a tightened axis is sometimes justified — then flag it explicitly.
Scales compare at equal scales. Two side-by-side charts with different axes suggest conclusions the data does not carry.
The title states the finding, not the variable: "Premium average basket doubled in 2026" informs; "Amount by segment" decorates. Add the source and the period — a chart always travels further than its context.
Color carries meaning or does not exist. Twelve colors for twelve bars encode nothing; one color for the highlighted segment and gray for the rest guides the eye to the message.
Exploration charts can stay rough — their only reader is you, their only purpose is to see. A chart shown to others follows the four rules, carries a finding-title and labeled axes with units. Confusing the two wastes time in one direction (polishing exploratory plots) and credibility in the other (presenting rough ones).
Key takeaways
- Plotting is a diagnostic act: two-hump distributions and outliers do not show up in
describe(). - Object-oriented style:
fig, ax = plt.subplots()thenax.set_...; the whole ecosystem produces touch-up-able Matplotlib axes. - Four questions, four charts: distribution → histogram, time → line, relationship → scatter, groups → bars/boxes.
- Seaborn +
huefor group comparisons in one line; correlation heatmap before any model. - Honesty: bars from zero, comparable scales, finding-titles, meaningful color.
Next module: virtual environments and dependency management — what makes your work installable somewhere other than your machine.