Data Visualization
Intermediate 13 min read Data Visualization

Matplotlib and Seaborn

Draw everything, beautifully, in code

The workhorses of Python charts: matplotlib's primitives and seaborn's statistical defaults. Master the palette, the axes object, and the faceting API once.

matplotlibseabornaxescatplotrelplotfacetGridstyles
Prerequisites: Chart Selection
Before we start

What you will learn

  • Control matplotlib figures/axes directly
  • Use seaborn's statistical plots and themes
  • Build small multiples with facets
Introduction

What is this?

matplotlib is the low-level engine (figures, axes, lines, bars); seaborn is the statistical layer built on it — nicer defaults for histograms, boxplots, regressions and faceted grids. A typical workflow: set a seaborn theme, then draw with either, styling roles deliberately: fig, ax = plt.subplots(...); ax.plot(...).

Motivation

Why do you need it?

  • Seaborn's defaults are publication-ready without hand-tuning ticks.
  • Faceting (col=, row=, hue=) turns one statement into small multiples in a line.
  • The axes object model makes fine control reproducible.
  • One stacked skill covers exploration, reports and dashboards.
Think about it

Mental model

Imagine

A draftsman's instruments plus a talented apprentice

Think of

matplotlib + seaborn

matplotlib is the plain drawing instruments — precise but manual. Seaborn is the apprentice who pre-sets the drawing layout, line weights and statistical summaries so you point at the statement and it appears; you still hold the instruments for custom strokes.

Mechanics

How it works

  • sns.set_theme(style/context/palette) sets global defaults once.
  • plt.subplots() returns (fig, ax); all plotting targets ax (or seaborn accepts ax=).
  • sns.histplot, sns.boxplot, sns.scatterplot, sns.regplot handle their statistical role.
  • sns.catplot(col=..., row=..., hue=...) facets categorical comparisons.
  • sns.relplot(col=...) facets relationships; displot facets distributions.
  • Fine control: ax.set_*, ax.legend, plt.tight_layout, fig.savefig(dpi=...).

Setup → draw → refine → export.

Theme
Canvas
Draw
Refine
Export
Hands-on

Examples

A faceted pair in one call

A faceted pair in one call
import numpy as np, pandas as pd
import matplotlib; matplotlib.use("Agg")
import matplotlib.pyplot as plt
import seaborn as sns
rng = np.random.default_rng(4)
df = pd.DataFrame({"plan": np.random.choice(["basic","pro"], 120),
"month": np.random.choice(["Jun","Jul"], 120),
"spend": np.round(rng.lognormal(2, .8, 120), 2)})
sns.set_theme(style="whitegrid")
g = sns.catplot(data=df, x="plan", y="spend", col="month", kind="box")
g.savefig("facet.png")
print("facet.png: one grid, two months")

catplot facets the same box comparison by month, and seaborn handles the panel scaffolding.

Real world

In production

  • A growth report's small-multiples grid reuses sns.catplot with fixed col order.
  • A research handoff exports all charts at consistent dpi and theme from one helper.
  • A DA dashboard derives its inline sparklines from matplotlib axes hooks.
Guidelines

Best practices

  • Set a theme/palette once at the top of the script.
  • Target ax for fine control instead of pyplot globals.
  • Prefer seaborn functions that accept data= and hue=/col= for facets.
  • tight_layout + savefig(dpi=150) before printing any report.
Watch out

Common mistakes

  • Mixing pyplot globals and axes objects so styling leaks across figures.
  • Overplotting scatter of 50k points — use alpha, sample or hexbin.
  • Facet plots with too many panels becoming unreadable.
  • Forgetting bbox_inches='tight' and clipping labels on export.
When things break

Debugging tips

  • A blank export → matplotlib.use('Agg') before plotting in headless contexts.
  • A facet missing a level → the data lacks that group; reorder via order=.
  • Legend clipping → loc/bbox_to_anchor and tight_layout.
  • When a seaborn layer and matplotlib layers collide, pass share axes explicitly.
Interviews

Interview checkpoint

Practice

Hands-on lab

Ship a Themed, Faceted Chart Panel
30 min · intermediate
In progress
Objectives
  • Configure a global theme and canvas
  • Draw a faceted comparison
  • Export publication-quality output

Ship a Themed, Faceted Chart Panel

30 min · intermediate

0/4 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Which API facets by row/col in one call?

2

Seaborn runs independently of matplotlib objects underneath.

Go deeper

Official documentation