matplotlib
matplotlib is Python's foundational plotting library. Control figures, axes, and every artist for publication-quality static charts.
Search across all documentation pages
matplotlib is Python's foundational plotting library. Control figures, axes, and every artist for publication-quality static charts.
Quick-reference recipe card - copy-paste ready.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot([1, 2, 3], [4, 1, 3], label="Series A")
ax.set(xlabel="Month", ylabel="Revenue", title="Q1 Performance")
ax.legend()
fig.savefig("q1.png", dpi=150, bbox_inches="tight")
plt.close(fig)When to reach for this:
.plot, or custom vizimport matplotlib.pyplot as plt
import numpy as np
months = np.arange(1, 13)
east = np.array([120, 130, 125, 140, 150, 155, 160, 158, 162, 170, 175, 180])
west = np.array([100, 105, 110, 108, 115, 120, 118, 122, 125, 130, 128, 135])
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4), sharey=True)
ax1.plot(months, east, marker="o", color="#2c7bb6", label="East")
ax1.plot(months, west, marker="s", color="#fdae61", label="West")
ax1.set(xlabel="Month", ylabel="Revenue ($k)", title="Regional Trends")
ax1.legend()
ax1.grid(True, alpha=0.3)
width = 0.35
ax2.bar(months - width/2, east, width, label="East", color="#2c7bb6")
ax2.bar(months + width/2, west, width, label="West", color="#fdae61")
ax2.set(xlabel="Month", title="Side-by-Side Comparison")
ax2.legend()
fig.suptitle("2025 Revenue Dashboard", fontsize=14)
fig.tight_layout()
fig.savefig("dashboard.png", dpi=200, bbox_inches="tight")
plt.close(fig)What this demonstrates:
fig and axsharey for comparable scalessuptitle, tight_layout, and high-dpi exportFigure holds artists; Axes provides coordinate system and plotting methods.plt.plot) is fine in notebooks; prefer OO in modules.draw - savefig renders off-screen.matplotlib.rcParams or style sheets.| Method | Purpose |
|---|---|
plot | Lines and markers |
bar / barh | Categorical comparisons |
hist | Distributions |
scatter | Two numeric variables |
annotate | Callouts |
import matplotlib.pyplot as plt
# Non-interactive backend for servers
import matplotlib
matplotlib.use("Agg")
# Date formatting on x-axis
import matplotlib.dates as mdates
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m"))fig, ax = plt.subplots() and plt.close(fig).tight_layout - axis labels clip in saved PNGs. Fix: fig.tight_layout() or constrained_layout=True at creation.s and raise alpha.plt.close(fig) each iteration.| Alternative | Use When | Don't Use When |
|---|---|---|
| seaborn | Statistical defaults and facets | You need low-level artist control |
| Plotly | Interactive hover/zoom | Static LaTeX papers |
| Altair | Declarative grammar specs | Highly custom annotations |
| ggplot (plotnine) | R ggplot familiarity | Team standardized on matplotlib |
Figure is the container; Axes is one plot area.pyplot is a stateful shortcut - convenient but brittle in apps.import matplotlib.pyplot as plt
plt.rcParams.update({"font.size": 12})ax.tick_params(axis="x", rotation=45)ax2 = ax.twinx()
ax2.plot(x, other_series, color="tab:orange")fig, axes = plt.subplots(2, 2, figsize=(8, 8))
axes[0, 1].plot(x, y)ax.plot calls with labels.Agg backend on headless servers.savefig before close.%matplotlib inline for static; avoid huge dpi in notebooks.ax.set_yscale("log")Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026