What Matplotlib is
Matplotlib is the foundational plotting library for Python. Nearly every other Python visualisation tool — Seaborn, pandas’ plotting methods, much of scikit-learn’s diagnostic output — is built on top of it, which means learning Matplotlib is learning the layer underneath most of the ecosystem.
The property that makes it the publication standard is control. Every element of a figure is an object you can address: the axis spine, the tick label, the legend frame, the width of a specific line. That is why its defaults look dated and its code is verbose — it is not optimised for a quick look at your data, it is optimised for producing exactly the figure someone specified. Journal figure requirements are exactly that kind of specification: 3.5 inches wide, 8-point sans-serif labels, 300 dpi, vector format, no transparency. Matplotlib is the most direct route from that list to a compliant file.
Why researchers use it
- Exact dimensional control — set the figure to your journal’s column width in inches, and what you get is that width, not something scaled to approximately it.
- Vector output — PDF, EPS, and SVG that stay sharp at any zoom and satisfy submission requirements without a resolution conversation.
- A style file makes consistency automatic — an
.mplstyleapplied across a project means every figure in your paper shares fonts, colours, and line weights without repeating the setup. - It is scriptable, so figures regenerate — the data changes, you re-run, and the figure updates. No re-drawing, no stale panel three.
- Animations —
FuncAnimationproduces convergence plots and simulation videos for talks, covered in the animation tutorial.
Where it fits in a research workflow
Matplotlib is the last computational step before a figure becomes a document. Upstream is your analysis in Jupyter or a script; downstream is a .pdf referenced from LaTeX or dropped into a Quarto manuscript, where re-rendering regenerates it from the data.
The pattern worth adopting deliberately is the two-layer one: generate the data layer in Matplotlib — axes, series, labels, everything driven by numbers — and if annotation or layout work remains, export SVG and finish in Inkscape. Keeping the data layer scripted means the figure updates when the data does; keeping the design layer separate means you are not encoding arrow positions in Python. Where it hands off entirely: Plotly when readers should explore the data rather than read it, and RStudio with ggplot2 if your analysis is in R.
Getting started
An afternoon to a compliant figure, and one habit that saves the rest of the project.
- Write an
.mplstylefile before your second figure. Font family, sizes, line widths, and a fixed colour cycle in one file, applied withplt.style.use(). This is the difference between a coherent paper and eight figures that disagree with each other. - Set the figure size in inches to your target column width and the font size to the journal’s caption size. Getting these right at generation time avoids the scaling that ruins text legibility.
- Save as PDF or SVG rather than PNG. Vector output is what journals want and what survives being resized.
- The step people skip: check your colour choices against colour-vision deficiency. Roughly one in twelve men cannot distinguish a red-green pair, and the default rainbow colormaps are actively bad. Use a perceptually uniform colormap and an accessible categorical palette; it costs one line and it is the most common reviewable flaw in scientific figures.
Matplotlib vs the alternatives
| Alternative | Does it better | Pick it if |
|---|---|---|
| Seaborn | Attractive statistical plots in far less code | You want a good default quickly, not exact control |
| Plotly | Interaction — hover, zoom, rotate | The figure is for a web supplement or a dashboard |
| ggplot2 in RStudio | A more coherent grammar and better defaults | Your analysis is in R |
| Inkscape | Hand-placed annotation and final layout | The figure is a diagram, not a plot of data |
Seaborn is not really a competitor — it produces Matplotlib figures you can then adjust with Matplotlib. Using both is the normal answer.
Cost, licensing, and your data
Free and open source under a BSD-style licence, developed by a community under the NumFOCUS umbrella with two decades of continuous development. Nothing to buy, no account, nothing leaves your machine.
The consideration that matters is longevity, and it is a strength: figures generated by a script are reproducible in a way figures drawn by hand are not, and Matplotlib’s API has been stable enough that decade-old plotting code still largely runs. Pin the version in your project environment anyway — default styling has changed across major releases, so a figure regenerated years later can differ subtly from the published one even when the data and code are identical.
The honest review
Strengths. Nothing else gives you this degree of control over a scientific figure, and control is precisely what publication requires. Combined with a style file, it turns “make eight figures that look like they belong to the same paper” from an act of discipline into a property of the setup. And because figures are generated from code, a reviewer’s request for a different subset is a re-run rather than an afternoon.
Limitations. The defaults are unattractive and the API is genuinely awkward — two overlapping interfaces (pyplot and the object-oriented one) that tutorials mix freely, and a verbosity that makes simple plots longer than they should be. Getting a figure to look good rather than merely correct takes real effort, which is why Seaborn exists. Interactive output is weak. And the learning curve is front-loaded in an unhelpful way: the concepts you need for publication-quality output are not the ones the beginner tutorials teach.
Verdict. Adopt it if you publish figures from Python data — there is no real alternative for camera-ready output. Skip it for exploratory plotting, where Seaborn’s defaults save you time, and for interactive work, where Plotly is built for the job. The condition that flips the answer is the destination: print journal, Matplotlib; web supplement, Plotly.
Common questions
Is Matplotlib free?
Yes — free and open source under a BSD-style licence, community-maintained under NumFOCUS, with no paid tier.
How do I make Matplotlib figures publication-ready?
Set the figure size in inches to your journal’s column width, set font sizes to match the caption size, export as PDF or SVG rather than PNG, and use a colour-vision-safe palette. Put all of it in an .mplstyle file so it applies to every figure automatically — the publication-quality walkthrough covers the details.
Matplotlib or Seaborn?
Both. Seaborn produces Matplotlib figures with better defaults and much less code, so use it to generate the plot and Matplotlib to adjust it for publication. They are layers, not alternatives.