Build a clearly labelled line chart and bar chart with matplotlib's figure and axes interface.
Why it matters
Matplotlib is the foundation of plotting in Python. pandas' .plot(), seaborn and many other libraries draw with it underneath, so knowing its core model lets you fix any chart, whatever library made it. You will run the plotting code on your own machine (Jupyter, VS Code or Google Colab); the in-browser activity focuses on the data preparation that every chart needs.
The core model: figure and axes
Matplotlib has two layers you will use constantly:
- Figure: the whole canvas (the image file or window).
- Axes: one plotting area inside the figure, with its own x-axis, y-axis, title and data. A figure can hold several axes.
Always start with plt.subplots(), which returns both:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 4)) # width, height in inches
Then call methods on ax: ax.plot, ax.bar, ax.set_title, ax.set_xlabel. This "object-oriented" style is clearer than calling plt.plot repeatedly, especially once you have more than one chart in a figure.
A labelled line chart
import pandas as pd
import matplotlib.pyplot as plt
orders = pd.read_csv("orders.csv", parse_dates=["date"])
monthly = orders.groupby(orders["date"].dt.strftime("%Y-%m"))["revenue"].sum()
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(monthly.index, monthly.values, marker="o", color="#1b9e77", linewidth=2)
ax.set_title("Monthly revenue, Jan to May 2026", loc="left")
ax.set_xlabel("Month")
ax.set_ylabel("Revenue ($)")
ax.set_ylim(bottom=0) # honest baseline
ax.spines[["top", "right"]].set_visible(False)
ax.grid(axis="y", color="#dddddd", linewidth=0.8)
fig.tight_layout()
fig.savefig("monthly_revenue.png", dpi=150)
What each part does:
groupby(...).sum()turns many orders into one value per month. Getting this step right is most of the work, which is why the activity practises it.marker="o"shows where the actual data points are, useful with few periods.set_ylim(bottom=0)is optional for line charts, but it avoids exaggerating small changes when your audience might over-read the slope.tight_layout()stops labels being cut off;savefigwrites a file at a sensible resolution.
A sorted bar chart
by_region = orders.groupby("region")["revenue"].sum().sort_values()
fig, ax = plt.subplots(figsize=(6, 3))
bars = ax.barh(by_region.index, by_region.values, color="#7570b3")
ax.bar_label(bars, fmt="{:,.0f}", padding=3)
ax.set_title("Revenue by region", loc="left")
ax.set_xlabel("Revenue ($)")
ax.spines[["top", "right"]].set_visible(False)
fig.tight_layout()
barh draws horizontal bars, which suit text labels. Matplotlib draws the first bar at the bottom, so sorting ascending puts the largest at the top. bar_label (matplotlib 3.4+) adds value labels, and fmt="{:,.0f}" adds thousands separators.
Several charts in one figure
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(11, 4))
ax1.plot(monthly.index, monthly.values)
ax2.barh(by_region.index, by_region.values)
fig.suptitle("Q1 to Q2 sales overview")
plt.subplots(rows, cols) returns an array of axes. You will use this for small multiples later in the module.
Saving and sharing
- Use
savefig("name.png", dpi=150)for slides and documents, or.svgfor crisp scaling on the web. - Set
figsizebefore plotting; resizing an image afterwards blurs text. - In Jupyter, a chart shows automatically at the end of a cell; in scripts, call
plt.show().
Common mistakes
- Mixing the
plt.andax.styles in the same figure. Titles end up on the wrong chart. Pickax.methods. - Plotting unaggregated data. Plotting 10,000 raw orders as a line gives a scribble. Aggregate first.
- Unsorted time. If months are strings, make sure they are sorted ("2026-10" sorts correctly; "Oct 2026" does not). Using ISO "YYYY-MM" strings or real dates avoids this.
- Missing units. "Revenue" alone does not say dollars or thousands of dollars.
- Default titles. Matplotlib adds none by default; always add one, ideally stating the takeaway.
Quick recap
fig, ax = plt.subplots()then call methods onax.- Aggregate with pandas, then plot:
ax.plotfor time,ax.barhfor sorted categories. - Label axes with units, set honest baselines, remove extra spines,
tight_layout(),savefig.
Try it
In the Do tab, use pandas to compute the monthly series and the sorted region totals that feed these two charts, plus a takeaway title.