Matplotlib
Matplotlib is the foundational plotting library of scientific Python. pandas plotting, seaborn, and many domain libraries build on it, and nearly every data science notebook and automated report uses it somewhere. It can produce almost any static chart — line, scatter, histogram, heatmap, contour, map projections — with complete control over every element, and export publication-quality vector or raster files.
That control comes with two interfaces and a large API. Most frustration with Matplotlib comes from mixing the implicit pyplot state machine with the explicit object-oriented API, and from defaults that are fine for exploration but not for reports others will read. Using the Figure and Axes API consistently, plus a few habits for accessibility and export, makes it predictable.
TL;DR
- A Figure contains one or more Axes; prefer the explicit API:
fig, ax = plt.subplots()thenax.plot(...). - Use
layout="constrained"for automatic spacing and small multiples with shared axes for comparisons. - Label everything — titles, axis labels with units, legends — and annotate the point of the chart.
- Use perceptually uniform, colorblind-safe colors and encode differences with markers or line styles, not color alone.
- Export SVG or PDF for documents and PNG at a set DPI for the web; record metadata about the generating script.
- In scripts and CI, use the non-interactive Agg backend and close figures to free memory.
Quick Example
An annotated, colorblind-friendly comparison chart exported for a report:
Core Concepts
Figures, Axes, and the Two Interfaces
The pyplot interface (plt.plot, plt.title) acts on the "current" figure and axes — convenient for quick looks, confusing with multiple plots. The object-oriented interface calls methods on explicit fig and ax objects and is the better default for anything you keep.
Layouts and Subplots
plt.subplots(nrows, ncols, sharex=True, sharey=True, layout="constrained") creates grids with consistent axes and spacing. Small multiples — the same chart repeated per segment with shared scales — are often clearer than one crowded plot. subplot_mosaic builds irregular layouts from a text template.
Plot Types
pandas (df.plot(ax=ax)) and seaborn draw onto Matplotlib axes, so you can combine them and finish styling with Matplotlib calls.
Styles and rcParams
rcParams control defaults: fonts, sizes, line widths, colors, and DPI. Style sheets (plt.style.use(...)) apply sets of them; a project style file keeps every chart consistent. Use with plt.style.context(...) to apply a style temporarily.
Color and Accessibility
- Use perceptually uniform colormaps such as
viridisorcividisfor continuous data, and diverging maps centered on a meaningful midpoint for signed data; avoid rainbow maps likejet. - Use colorblind-safe qualitative palettes (for example
tableau-colorblind10) for categories. - Add redundant encodings — markers, line styles, direct labels — so charts work in grayscale and for color vision deficiencies.
- Keep font sizes readable at the final display size and ensure sufficient contrast.
See Accessibility.
Exporting for Reports
- Vector formats (SVG, PDF) stay sharp at any size for documents and slides; PNG at an explicit
dpisuits web pages. bbox_inches="tight"trims excess whitespace when not using constrained layout.- Metadata (creator script, date, data snapshot) in saved files supports reproducibility; also commit the script that generated each figure.
- Set
svg.hashsaltand avoid timestamps in metadata when you need byte-identical files across runs.
Scripts, CI, and Performance
- Backends: in scripts and CI, use the non-interactive Agg backend (
MPLBACKEND=Aggormatplotlib.use("Agg")) so no display is required. - Memory: figures persist until closed; call
plt.close(fig)when generating many charts in loops. - Large data: plot aggregated or downsampled data, use
hexbinor 2D histograms for dense scatters, andrasterized=Truefor huge point clouds in vector output. - Testing charts: compare images in tests with tolerance (for example pytest-mpl) for reports that must stay stable.
Best Practices
Use the Object-Oriented API
Create figures and axes explicitly and call methods on them; it avoids state-related surprises and scales to multi-panel figures.
Make the Point Obvious
Title charts with the takeaway, annotate key events, and remove clutter such as heavy grids and unnecessary legends.
Share Axes When Comparing
Small multiples with shared scales prevent readers from misjudging differences across panels.
Keep a Project Style
Define fonts, sizes, and palettes once in a style file so every figure in a report matches.
Common Mistakes
Mixing pyplot and Object-Oriented Calls
Color as the Only Encoding
Leaking Figures in Loops
FAQ
What is the difference between pyplot and the object-oriented API?
pyplot functions operate on an implicit current figure and axes, which is convenient for quick plots. The object-oriented API calls methods on explicit Figure and Axes objects, which is clearer and more reliable for multi-panel and reusable charts.
How do I make Matplotlib charts accessible?
Use colorblind-safe palettes and perceptually uniform colormaps, encode categories with markers or line styles as well as color, label axes with units, use readable font sizes, and provide text descriptions where charts are published.
Should I save figures as PNG or SVG?
SVG or PDF for documents and print, since vectors scale without blurring; PNG with an explicit DPI for web pages and contexts that do not support vector images.
How do I use Matplotlib without a display?
Select the non-interactive Agg backend, for example by setting the MPLBACKEND=Agg environment variable, and save figures to files instead of showing them.
Matplotlib or seaborn?
seaborn provides high-level statistical charts with good defaults and builds on Matplotlib. Many people use seaborn for the chart and Matplotlib for fine-tuning and export.
Related Topics
- Exploratory Data Analysis and Visualization — Where charts fit in analysis
- Python for Data Science — The scientific Python stack
- pandas — Plotting directly from DataFrames
- Accessibility — Inclusive design principles
- Python — The language
- Scikit-learn — Visualizing model results