Appendix D: matplotlib Cheatsheet
A quick reference for the most common matplotlib operations. Every snippet uses the explicit object-oriented (fig/ax) interface, which is the recommended approach for any chart that goes beyond a one-liner.
The fig/ax Pattern
Always start here. The Figure is the canvas; the Axes is where data gets drawn.
import matplotlib.pyplot as plt
import numpy as np
# Single plot
fig, ax = plt.subplots(figsize=(8, 5))
# Multiple subplots (2 rows, 3 columns)
fig, axes = plt.subplots(2, 3, figsize=(14, 8))
ax = axes[0, 1] # access row 0, column 1
# Unequal grid with GridSpec
from matplotlib.gridspec import GridSpec
fig = plt.figure(figsize=(10, 8))
gs = GridSpec(2, 3, figure=fig)
ax_big = fig.add_subplot(gs[0, :]) # top row, full width
ax_left = fig.add_subplot(gs[1, 0]) # bottom-left
ax_right = fig.add_subplot(gs[1, 1:]) # bottom-right, spans 2 cols
Common Plot Types
Line Plot
ax.plot(x, y, color="#1F77B4", linewidth=1.5, linestyle="-", label="Series A")
ax.plot(x, y2, color="#FF7F0E", linewidth=1.5, linestyle="--", label="Series B")
Bar Chart
# Vertical
ax.bar(categories, values, color="#2CA02C", edgecolor="white", width=0.6)
# Horizontal
ax.barh(categories, values, color="#D62728", edgecolor="white", height=0.6)
# Grouped bars
x_pos = np.arange(len(categories))
width = 0.35
ax.bar(x_pos - width/2, vals_a, width, label="Group A")
ax.bar(x_pos + width/2, vals_b, width, label="Group B")
ax.set_xticks(x_pos)
ax.set_xticklabels(categories)
Scatter Plot
ax.scatter(x, y, s=50, c=color_values, cmap="viridis",
alpha=0.7, edgecolors="white", linewidth=0.5)
Histogram
ax.hist(data, bins=30, color="#9467BD", edgecolor="white", alpha=0.8)
# Overlapping histograms
ax.hist(data_a, bins=30, alpha=0.5, label="A")
ax.hist(data_b, bins=30, alpha=0.5, label="B")
Box Plot
bp = ax.boxplot([data_a, data_b, data_c], labels=["A", "B", "C"],
patch_artist=True, widths=0.5)
for patch, color in zip(bp["boxes"], ["#1F77B4", "#FF7F0E", "#2CA02C"]):
patch.set_facecolor(color)
Heatmap
im = ax.imshow(matrix, cmap="RdBu_r", aspect="auto", vmin=-1, vmax=1)
fig.colorbar(im, ax=ax, shrink=0.8)
Pie Chart
ax.pie(sizes, labels=labels, autopct="%1.1f%%",
colors=["#1F77B4", "#FF7F0E", "#2CA02C", "#D62728"],
startangle=90, wedgeprops={"edgecolor": "white"})
ax.set_aspect("equal")
Area / Fill
ax.fill_between(x, y_lower, y_upper, alpha=0.3, color="#1F77B4", label="Range")
ax.plot(x, y_mean, color="#1F77B4", label="Mean")
Titles, Labels, and Text
# Title and axis labels
ax.set_title("Chart Title", fontsize=14, fontweight="bold", pad=12)
ax.set_xlabel("X-axis Label", fontsize=11)
ax.set_ylabel("Y-axis Label", fontsize=11)
# Suptitle for multi-panel figures
fig.suptitle("Overall Figure Title", fontsize=16, fontweight="bold", y=0.98)
# Text annotation at a data point
ax.annotate("Peak", xy=(x_peak, y_peak), xytext=(x_peak + 1, y_peak + 5),
fontsize=10, arrowprops=dict(arrowstyle="->", color="gray"))
# Freestanding text
ax.text(0.02, 0.95, "n = 1,042", transform=ax.transAxes,
fontsize=9, verticalalignment="top", color="gray")
Legend
# Default (auto-placed)
ax.legend()
# Custom placement
ax.legend(loc="upper left", frameon=False, fontsize=10)
# Outside the plot area
ax.legend(bbox_to_anchor=(1.02, 1), loc="upper left", borderaxespad=0)
fig.subplots_adjust(right=0.8) # make room
# Custom handles
from matplotlib.lines import Line2D
handles = [Line2D([0], [0], color=c, lw=2) for c in ["#1F77B4", "#FF7F0E"]]
ax.legend(handles, ["Series A", "Series B"])
Colors and Colormaps
# Named color
ax.plot(x, y, color="steelblue")
# Hex code
ax.plot(x, y, color="#E69F00")
# RGB tuple (0-1 range)
ax.plot(x, y, color=(0.2, 0.4, 0.6))
# Set default color cycle
plt.rcParams["axes.prop_cycle"] = plt.cycler(color=["#1F77B4", "#FF7F0E", "#2CA02C"])
# Access a colormap
cmap = plt.get_cmap("viridis")
color = cmap(0.5) # returns RGBA tuple at the midpoint
Axis Formatting
# Limits
ax.set_xlim(0, 100)
ax.set_ylim(-10, 10)
# Ticks
ax.set_xticks([0, 25, 50, 75, 100])
ax.set_xticklabels(["0", "25", "50", "75", "100"], fontsize=9)
ax.tick_params(axis="both", which="major", labelsize=9, length=4)
# Format tick labels with a function
from matplotlib.ticker import FuncFormatter
ax.yaxis.set_major_formatter(FuncFormatter(lambda v, _: f"${v:,.0f}"))
# Log scale
ax.set_yscale("log")
# Invert axis
ax.invert_yaxis()
Grid and Spines
# Light grid
ax.grid(True, axis="y", linestyle="--", linewidth=0.5, alpha=0.5)
# Remove top and right spines (recommended default)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
# Remove all spines
for spine in ax.spines.values():
spine.set_visible(False)
# Move bottom spine
ax.spines["bottom"].set_position(("data", 0))
Saving Figures
# PNG for screen (default)
fig.savefig("chart.png", dpi=150, bbox_inches="tight", facecolor="white")
# High-resolution PNG for print
fig.savefig("chart_print.png", dpi=300, bbox_inches="tight")
# Vector formats for publication
fig.savefig("chart.pdf", bbox_inches="tight")
fig.savefig("chart.svg", bbox_inches="tight")
# Transparent background
fig.savefig("chart.png", dpi=150, bbox_inches="tight", transparent=True)
Style Sheets
# Use a built-in style
plt.style.use("seaborn-v0_8-whitegrid")
# Stack styles
plt.style.use(["seaborn-v0_8-whitegrid", "presentation"])
# Temporary style context
with plt.style.context("ggplot"):
fig, ax = plt.subplots()
ax.plot(x, y)
# List all available styles
print(plt.style.available)
rcParams Quick Reference
Override defaults globally before creating any figures:
plt.rcParams.update({
"figure.figsize": (8, 5),
"figure.dpi": 150,
"axes.titlesize": 14,
"axes.labelsize": 12,
"axes.spines.top": False,
"axes.spines.right": False,
"lines.linewidth": 1.5,
"font.family": "sans-serif",
"font.sans-serif": ["Helvetica", "Arial", "DejaVu Sans"],
"legend.frameon": False,
"savefig.bbox": "tight",
"savefig.dpi": 300,
})
Useful Patterns
Add a Horizontal or Vertical Reference Line
ax.axhline(y=0, color="gray", linewidth=0.8, linestyle="--")
ax.axvline(x=threshold, color="red", linewidth=0.8, linestyle=":")
Shade a Region
ax.axvspan(xmin=recession_start, xmax=recession_end, alpha=0.15, color="gray")
Secondary Y-Axis
ax2 = ax.twinx()
ax2.plot(x, y2, color="#D62728")
ax2.set_ylabel("Secondary Metric")
Tight Layout (Prevent Overlapping Labels)
fig.tight_layout()
# Or use constrained_layout at creation:
fig, ax = plt.subplots(figsize=(8, 5), constrained_layout=True)