Learning Goals
3 min- Install matplotlib;
import matplotlib.pyplot as plt. - Draw a bar chart with
plt.bar(x, y). - Title, axis labels, rotated x-ticks.
- Annotate bars with their values.
- Save the figure to PNG.
Warm-Up · 4 Lines, 1 Chart
5 minpip install matplotlib
import matplotlib.pyplot as plt products = ["Pancake", "Cocoa", "Rice", "Tea"] revenue = [120, 95, 180, 60] plt.bar(products, revenue) plt.show()
You'll get a window with four blue bars. It works. Now we make it presentable.
Default matplotlib is ugly on purpose — it's the canvas you customise. Five extra lines (title, labels, color, rotation, value text) turn the warm-up plot into something you'd ship.
New Concept · plt.bar & the Customisations
14 minPyplot vs OO
Two styles exist; both work. We'll use OO (object-oriented) — it scales to subplots:
import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(8, 5)) ax.bar(products, revenue) plt.show()
Title + axis labels
ax.set_title("Revenue by product · May 2026") ax.set_xlabel("Product") ax.set_ylabel("Revenue ($)")
Colour and edge
bars = ax.bar(products, revenue, color="#4a90e2", edgecolor="black", linewidth=0.5)
Rotated x labels (when names are long)
ax.tick_params(axis="x", rotation=30) # or plt.xticks(rotation=30, ha="right")
Value annotations on each bar
for bar in bars: h = bar.get_height() ax.text(bar.get_x() + bar.get_width() / 2, h + 2, f"{h}", ha="center", va="bottom", fontsize=9)
Tight layout + save
fig.tight_layout() fig.savefig("revenue.png", dpi=200)
Worked Example · Polished Bar Chart
12 min# bar.py — production-quality bar chart import matplotlib.pyplot as plt products = ["Pancake", "Cocoa", "Rice", "Tea"] revenue = [120, 95, 180, 60] fig, ax = plt.subplots(figsize=(8, 5)) bars = ax.bar(products, revenue, color=["#4a90e2", "#e2884a", "#4ae28d", "#e24a8d"], edgecolor="black", linewidth=0.5) ax.set_title("Revenue by product · May 2026", fontsize=14, pad=10) ax.set_xlabel("Product") ax.set_ylabel("Revenue ($)") ax.set_ylim(0, max(revenue) * 1.15) ax.grid(axis="y", linestyle="--", alpha=0.4) for bar in bars: h = bar.get_height() ax.text(bar.get_x() + bar.get_width() / 2, h + 3, f"$ {h}", ha="center", va="bottom", fontsize=10) fig.tight_layout() fig.savefig("revenue.png", dpi=200) plt.show()
Open revenue.png in any image viewer. You get a chart you could paste straight into a school presentation. Five elements made the difference:
- Distinct colours per bar.
- Annotated values above each bar.
- Horizontal grid for easier reading.
- Extra y-axis headroom so labels don't collide.
tight_layoutprevents the title or labels being clipped.
Basic
5 minUse ax.barh(...) for horizontal bars instead. Useful when names are long.
Challenge 1
4 minSort the products so the tallest bar is on the left. Then add a colour scheme that goes dark → light.
Hint
import matplotlib.cm as cm pairs = sorted(zip(products, revenue), key=lambda p: -p[1]) products, revenue = zip(*pairs) colors = cm.Blues([1 - i / len(products) for i in range(len(products))]) ax.bar(products, revenue, color=colors)
Challenge 2
4 minCompare last month vs this month: two bars per product, side by side.
Hint
import numpy as np last = [110, 90, 160, 55] this = [120, 95, 180, 60] x = np.arange(len(products)) w = 0.4 fig, ax = plt.subplots() ax.bar(x - w/2, last, w, label="Apr") ax.bar(x + w/2, this, w, label="May") ax.set_xticks(x, products) ax.legend()
Challenge 3 · Bar From a CSV
8 minRead clean.csv, compute revenue per product with pandas, draw a sorted bar chart with annotations, save to revenue.png.
Show one possible solution
import pandas as pd, matplotlib.pyplot as plt df = pd.read_csv("clean.csv") df["total"] = df["quantity"] * df["price"] rev = (df.groupby("product")["total"].sum() .sort_values(ascending=False)) fig, ax = plt.subplots(figsize=(8, 5)) bars = ax.bar(rev.index, rev.values, color="#4a90e2", edgecolor="black") ax.set_title("Revenue by product") ax.set_ylabel("$") for b in bars: ax.text(b.get_x() + b.get_width()/2, b.get_height() + 0.3, f"$ {b.get_height():.0f}", ha="center") fig.tight_layout() fig.savefig("revenue.png", dpi=200)
Recap
3 minBars in 4 lines; presentable bars in 10. Use the OO style (fig, ax = plt.subplots()) — it carries over to subplots tomorrow. Always title + label + save. Annotations beat tooltips for static reports.
Extra Mission
4 minDraw a polished bar chart of any aggregate from your real CSV. Hit all five rules: title, labels, sorted, annotated, saved as PNG.