Your first plot
Six lines, and five of them are about being readable
plt.subplotsax.plotax.set_xlabelax.set_titleax.legendax.gridWatch it happen
Play it through, or step back and forth yourself.
fig, ax = plt.subplots(figsize=(6, 3.5))
ax.plot(days, delhi)
ax.set_xlabel("day")
ax.set_ylabel("cups")ax.set_title("Cups sold this week")ax.plot(days, mumbai, label="Mumbai") ax.legend()
ax.grid(True, alpha=0.3)
fig, ax = plt.subplots() makes a Figure with one Axes inside it and hands you both. Nothing is drawn yet — this is the frame you're about to put data in. figsize is in inches, which is a hint about matplotlib's age.
The idea
Here is the whole thing, and then we'll take it apart line by line.
fig, ax = plt.subplots(figsize=(6, 3.5))
ax.plot(days, delhi, label="Delhi")
ax.plot(days, mumbai, label="Mumbai")
ax.set_xlabel("day")
ax.set_ylabel("cups")
ax.set_title("Cups sold this week")
ax.legend()
ax.grid(True, alpha=0.3)Notice the proportion: two lines put data on the chart and six make it legible. That ratio is normal, and it's the part tutorials skip.
The frame
plt.subplots() is the one you should reach for by default. It creates a Figure with one Axes inside and returns both. figsize is in inches — width first — which tells you roughly how old this library is. Multiply by dpi for pixels.
The data
ax.plot(days, delhi) # x first, then yWith one argument, ax.plot(delhi), matplotlib uses 0, 1, 2… as x — handy, and an easy way to draw the wrong chart without noticing. Pass both.
Call plot again on the same Axes and it draws on top, taking the next colour from the property cycle. You don't pick colours unless you want to; the cycle keeps series distinguishable for you. Common overrides:
ax.plot(days, delhi, color="#66aaf9", linewidth=2,
linestyle="--", marker="o", alpha=0.8)There's also the compact format string — ax.plot(x, y, "r--o") for a red dashed line with circle markers. It's terse and it appears everywhere online, but the keyword form is the one to write: it's readable a month later.
Saying what it is
set_xlabel, set_ylabel, set_title. Nothing adds these for you, and an unlabelled axis is a chart that only makes sense to the person who made it, for about twenty minutes.
Units belong in the label: "revenue (₹ thousands)", not "revenue". And a title is better spent on the finding than the columns — "Weekend trade is up 40%" beats "cups by day", because the axis labels already said what the columns are.
The legend
ax.legend() builds itself from the label= you passed to each plotting call. No labels, no legend — you'll get an empty box and a warning instead. Two arguments earn their keep:
ax.legend(loc="upper left") # or "best", the default
ax.legend(frameon=False) # no box — usually cleanerWith a single series, skip the legend entirely and put the name in the title. A legend explaining one line is furniture.
The grid
ax.grid(True, alpha=0.3). Faint on purpose — it should help the eye carry a value across to the axis without competing with the data. A grid at full strength is a cage.
Checking what you got
Every setter has a matching getter, which is how you verify a chart without squinting:
ax.get_title() ax.get_xlabel() ax.get_ylim()
len(ax.lines) ax.lines[0].get_color()See it run
The lesson's code, ready to run and to fiddle with.
Putting the kettle on…
Starting up…
Worked example
not gradedAlready written and ready to go — press Run to see what it does, then change a number, a column name, anything, and run it again.
trydeleting the label= arguments and re-running — watch the legend complain.
Your turn
3 exercises. Write the code yourself, then press Check — a nudge and the answer are there if you want them.
Plot delhi and mumbai against days on the same Axes, then return how many lines the Axes is holding.
Plot delhi, label the x axis "day" and the y axis "cups", and title it "Cups sold this week". Return the three strings back as a list, in that order.
Plot both cities with label= set to "Delhi" and "Mumbai", add a legend, and return the list of texts the legend ended up showing.
