Skip to main content

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.

QuestionChartTypical command
How is a variable distributed?Histogramax.hist(x, bins=40) / sns.histplot
How does it evolve over time?Lineax.plot(dates, y)
How are two variables related?Scatter plotax.scatter(x, y) / sns.scatterplot
How do groups compare?Bars or boxesax.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.

The diagnostic chart vs the presentation chart

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() then ax.set_...; the whole ecosystem produces touch-up-able Matplotlib axes.
  • Four questions, four charts: distribution → histogram, time → line, relationship → scatter, groups → bars/boxes.
  • Seaborn + hue for 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.