How to use this roadmap
- Follow Day 1 then Day 2. Each block has Topic, Why, Key Functions, and a Mini‑Task.
- Use the OO API (Object‑Oriented) from the start: fig, ax = plt.subplots().
- Practice with tiny arrays or a simple CSV so you focus on visuals, not data wrangling.
Day 1 — Foundations & Core Plots
Block | Topic | Why it matters | Key functions (syntax) | Mini‑task |
---|---|---|---|---|
1 | Setup & Basics Pyplot vs OO API, Figure & Axes |
Everything in Matplotlib lives on an Axes. OO gives full control. |
import matplotlib.pyplot as plt
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6,4))
ax.plot(x, y)
|
Create an empty figure and set a title. |
2 | Line plots most common | Show trends over ordered x. |
ax.plot(x, y, linestyle='-', marker='o')
ax.set(title='Line', xlabel='x', ylabel='y')
ax.legend()
|
Plot two lines with labels & legend. |
3 | Scatter plots | Relationship between two variables; density via alpha. |
ax.scatter(x, y, s=40, alpha=0.7)
ax.grid(True, linestyle=':')
|
Make a scatter and add grid & axis labels. |
4 | Bar charts (vertical & horizontal) | Compare categories; horizontal for long labels. |
ax.bar(categories, values)
ax.barh(categories, values)
ax.set_ylim/ set_xlim
|
Build both bar and barh for the same data. |
5 | Histograms & Density | Distribution, outliers, skew. |
ax.hist(x, bins=20, density=True)
ax.stairs(h, edges)
|
Plot histogram with 10 vs 30 bins; compare. |
6 | Box / Violin plots | Summarize spread & outliers across groups. |
ax.boxplot(data)
ax.violinplot(data)
|
Show boxplot of 3 groups side‑by‑side. |
7 | Pie / Donut (use sparingly) careful | Simple share at a glance; hard to compare many slices. |
ax.pie(values, labels=labels, autopct='%1.1f%%')
# Donut: add circle
|
Create a donut with 4 categories. |
8 | Annotations & Text | Call out key points; make plots readable. |
ax.annotate('note', xy=(x0,y0), xytext=(x1,y1), arrowprops={})
ax.text(0.5, 0.9, 'hello', transform=ax.transAxes)
|
Annotate the max point with an arrow. |
9 | Legends, Ticks, Spines | Professional polish. |
ax.legend(loc='best')
ax.set_xticks([...]); ax.set_xticklabels([...], rotation=45)
for s in ax.spines.values(): s.set_visible(True)
|
Rotate x‑tick labels; move legend outside. |
10 | Saving Figures | Share your work crisply for reports. |
fig.tight_layout()
fig.savefig('plot.png', dpi=300, bbox_inches='tight')
|
Export PNG and PDF at 300 DPI. |
Day 2 — Layouts, Scales, Images, Advanced
Block | Topic | Why it matters | Key functions (syntax) | Mini‑task |
---|---|---|---|---|
1 | Subplots & Layouts | Show multiple views; avoid clutter. |
fig, axs = plt.subplots(2,2, figsize=(8,6), sharex=True)
fig.tight_layout(); fig.subplots_adjust()
plt.GridSpec(nrows, ncols)
|
Make a 2×2 dashboard of four plot types. |
2 | Dual/Secondary Axes | Compare variables with different scales. |
ax2 = ax.twinx()
ax.secondary_xaxis('top', functions=(fwd, inv))
|
Plot temp (°C) and rain (mm) together. |
3 | Scales & Limits | Reveal patterns with log/symlog. |
ax.set_xscale('log'); ax.set_yscale('symlog')
ax.set_xlim(a,b); ax.set_ylim(c,d)
|
Compare linear vs log y‑scale for the same data. |
4 | Colormaps & Colorbars | Encode magnitude with color; readable color choices. |
im = ax.imshow(img, cmap='viridis')
fig.colorbar(im, ax=ax)
plt.colormaps()
|
Heatmap with colorbar and title. |
5 | Images & Heatmaps | Work with 2D arrays and images. |
ax.imshow(A, aspect='auto', interpolation='nearest')
ax.pcolormesh(X, Y, Z)
ax.contour/contourf(X, Y, Z)
|
Plot imshow + contour overlay. |
6 | Error bars & Confidence | Show uncertainty honestly. |
ax.errorbar(x, y, yerr=err, fmt='o')
ax.fill_between(x, y1, y2, alpha=0.3)
|
Line + shaded 95% band. |
7 | Time Series & Dates | Pretty date ticks and formatting. |
import matplotlib.dates as mdates
ax.plot(dates, values)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
fig.autofmt_xdate()
|
Plot monthly data with rotated labels. |
8 | 3D Basics | Surface/mesh for advanced visuals. |
from mpl_toolkits.mplot3d import Axes3D
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z)
|
Make a simple 3D surface. |
9 | Styling & Themes | Consistent, beautiful plots. |
plt.style.available; plt.style.use('ggplot')
plt.rcParams['font.size']=12
fig.set_facecolor('#fff'); ax.set_facecolor('#f7f7f7')
|
Apply a style + custom font size. |
10 | Export like a Pro | Quality + reproducibility. |
fig.savefig('figure.svg')
fig.savefig('figure.png', dpi=300, transparent=True)
fig.set_dpi(150)
|
Save transparent PNG and an SVG. |
Master Function Cheat‑Sheet (with what they do)
Function | What it does | Quick syntax |
---|---|---|
plt.subplots | Create figure and axes grid | fig, ax = plt.subplots(1,1, figsize=(6,4)) |
ax.plot | Line plot | ax.plot(x, y, linestyle='--', marker='o') |
ax.scatter | Scatter plot | ax.scatter(x, y, s=40, alpha=.7) |
ax.bar / ax.barh | Vertical / horizontal bars | ax.bar(cats, vals) |
ax.hist | Histogram of distribution | ax.hist(x, bins=20, density=True) |
ax.boxplot / ax.violinplot | Spread & outliers by group | ax.boxplot([a,b,c]) |
ax.pie | Pie chart (use sparingly) | ax.pie(vals, labels=labels, autopct='%1.1f%%') |
ax.errorbar | Values with error bars | ax.errorbar(x,y,yerr=err,fmt='o') |
ax.fill_between | Shade region between curves | ax.fill_between(x, y1, y2, alpha=.3) |
ax.step / ax.stem | Step or lollipop style | ax.step(x,y) |
ax.area / plt.stackplot | Area & stacked area | plt.stackplot(x, y_list) |
ax.imshow | Display image / 2D array | im=ax.imshow(A, cmap='magma') |
ax.pcolormesh / ax.contour(f) | Heatmap / contour lines | ax.contourf(X,Y,Z,levels=20) |
fig.colorbar | Attach colorbar to mappable | fig.colorbar(im, ax=ax) |
ax.annotate / ax.text | Notes and labels | ax.annotate('peak', xy=(...), xytext=(...)) |
ax.set / set_xlabel / set_ylabel | Titles & axis labels | ax.set(title='T', xlabel='X', ylabel='Y') |
ax.set_xlim / set_ylim | Axis limits | ax.set_xlim(0,100) |
ax.set_xscale / set_yscale | Log, symlog, etc. | ax.set_yscale('log') |
ax.legend | Legend for labeled artists | ax.legend(loc='best') |
ax.grid | Grid lines | ax.grid(True, linestyle=':') |
ax.twinx / secondary_xaxis | Secondary axes | ax2 = ax.twinx() |
plt.style.use | Apply style theme | plt.style.use('seaborn-v0_8') |
plt.rcParams[...] | Global defaults | plt.rcParams['axes.titlesize']=14 |
fig.tight_layout / constrained_layout | Auto layout | fig.tight_layout() |
fig.savefig | Export figures | fig.savefig('out.png', dpi=300) |
Nice‑to‑Know Extras
- inset_axes (from mpl_toolkits.axes_grid1.inset_locator) for zoomed inset plots.
- broken_barh for Gantt‑like timelines.
- axhline / axvline / axhspan / axvspan to mark thresholds/regions.
- FuncAnimation for simple animations/GIFs.
- Path / Patches for custom shapes (arrows, boxes).
Beginner‑Friendly Templates
Line + Scatter
import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(6,4)) ax.plot(x, y, label='Line', marker='o') ax.scatter(x, y2, label='Scatter', alpha=0.7) ax.set(title='My Plot', xlabel='X', ylabel='Y') ax.legend(); ax.grid(True, linestyle=':') fig.tight_layout(); fig.savefig('plot.png', dpi=300)
Heatmap + Colorbar
im = ax.imshow(A, cmap='viridis', aspect='auto') fig.colorbar(im, ax=ax); ax.set(title='Heatmap')
Mini Projects (end of each day)
- Day 1 Dashboard: 2×2 subplots: line, scatter, bar, histogram. Add titles, legend, grid, and export PNG.
- Day 2 Story: Heatmap with colorbar, a line plot with shaded CI, and a date‑xaxis plot. Save transparent PNG + SVG.
Tip: Keep code blocks short and readable. Prefer ax = axs[r, c] naming for multi‑plot grids.
Common Mistakes & Fixes
Mistake | Fix |
---|---|
Using only plt.plot everywhere | Switch to OO: fig, ax = plt.subplots() then ax.plot(...) |
Overlapping labels/legends | fig.tight_layout() or bbox_inches='tight' on save; reduce text size. |
Unreadable colors | Use perceptually uniform colormaps: 'viridis', 'magma', 'cividis'. |
Too many slices in pie charts | Use bar chart or small multiples instead. |
Axis scales hide structure | Try ax.set_yscale('log') for skewed data. |
Practice Plan (2 Days)
- Re‑type each example; don’t copy‑paste. Change one parameter and observe.
- Create a 2×2 dashboard twice: first with random data, then with a small CSV.
- Finish Day‑2 by rebuilding the same plots using different styles and colormaps.