Module 4 · Section 2 of 10
Lesson 4.1 - Matplotlib Fundamentals
Target: ~9 min read - 20 min hands-on
Overview
Every matplotlib chart is built from a Figure (the whole canvas) and one or more Axes (the plot areas within it). We'll cover the four workhorse chart types - line, bar, scatter, histogram - plus basic styling and saving output as PNG or PDF for a report.
Why This Matters (Engineering Context)
Every engineering report - an energy audit, a QA/QC memo, a feasibility study - eventually needs a static, print-ready chart. Matplotlib's PDF/PNG export produces it directly from your analysis code, with no "redraw it in Excel" step.
Code-Along
# One site's daily series, in date order, is our example data for this lesson
site1 = df[df["site"] == "Charlie DC"].sort_values("date")
# plt.subplots() returns a Figure (the whole canvas) and an Axes (one plot area).
# You draw onto the Axes (ax) and set its labels/title, then show the Figure.
fig, ax = plt.subplots(figsize=(9, 4))
ax.plot(site1["date"], site1["energy_kwh"], linewidth=0.8, color="steelblue") # line chart
ax.set_title("Charlie DC Daily Energy, 2023")
ax.set_xlabel("Date"); ax.set_ylabel("Energy (kWh)")
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b")) # show month names on the x-axis
plt.tight_layout(); plt.show() # tidy spacing, then render
# --- Bar chart: one bar per month ---
monthly = site1.assign(month=site1["date"].dt.month).groupby("month")["energy_kwh"].sum()
fig, ax = plt.subplots(figsize=(8, 4))
ax.bar(monthly.index, monthly.values, color="teal") # .index -> x, .values -> bar heights
ax.set_xticks(range(1, 13))
ax.set_title("Charlie DC Monthly Energy Total, 2023")
ax.set_xlabel("Month"); ax.set_ylabel("Total Energy (kWh)")
plt.tight_layout(); plt.show()
# --- Scatter: one dot per day; alpha<1 makes overlapping points readable ---
fig, ax = plt.subplots(figsize=(6, 5))
ax.scatter(site1["ambient_c"], site1["energy_kwh"], alpha=0.4, s=15, color="darkorange") # s = dot size
ax.set_title("Energy vs Ambient Temperature - Charlie DC")
ax.set_xlabel("Ambient Temp (C)"); ax.set_ylabel("Energy (kWh)")
plt.tight_layout(); plt.show()
# --- Histogram: bins the values and counts how many fall in each bin ---
fig, ax = plt.subplots(figsize=(7, 4))
ax.hist(site1["energy_kwh"], bins=25, color="slateblue", edgecolor="white")
ax.set_title("Distribution of Daily Energy - Charlie DC")
ax.set_xlabel("Energy (kWh)"); ax.set_ylabel("Number of Days")
plt.tight_layout(); plt.show()
# Save the last figure for a report. PDF/SVG stay sharp at any zoom; PNG is raster.
fig.savefig("m4_energy_hist.png", dpi=150, bbox_inches="tight") # bbox_inches: trim whitespace
fig.savefig("m4_energy_hist.pdf", bbox_inches="tight")
print("Saved m4_energy_hist.png and .pdf")
Run it: four charts render inline - a line chart, a bar chart, a scatter plot, and a histogram - followed by a confirmation that PNG and PDF versions were saved. PDF preserves vector quality (crisp at any zoom), which matters for print-quality reports; PNG is better for quick previews or slides.
Practice Exercises
- Change the line chart's color and line width, and add grid lines with
ax.grid(True, alpha=0.3). - Build a bar chart comparing total annual energy across all 5 sites (not just Charlie DC).
- Save one chart as
.svginstead of PNG/PDF - when is vector SVG preferable to PNG?
# Try the practice exercises here
Knowledge Check
- What are the two core objects that make up every matplotlib chart?
- Which export format preserves vector (infinitely zoomable) quality: PNG or PDF?
- What method displays a chart inline in a notebook?
Answer key
- Figure and Axes
- PDF (and SVG)
plt.show()
35 / 63 sections · Course home · Join the coaching cohort