Matplotlib·Lesson 5·12 min·0/3 exercises

Lines

What the segment between two points is actually claiming

ax.plotlinestylemarkerax.fill_betweenax.axhlineax.stackplot

Watch it happen

Play it through, or step back and forth yourself.

MonTueWedThuFriSatSun050100Cups sold this weekdaycups
ax.plot(x, y)x first, then y
ax.plot(y)x becomes 0, 1, 2, …
ax.plot(x, y1, x, y2)two series in one call
label="Delhi"what the legend will say

A line chart says one thing that a scatter doesn't: the segment between two points is real. Wednesday to Thursday, the value passed through everything in between. Draw a line only when that sentence is true.

The idea

A line chart makes a claim a scatter doesn't. The segment between Wednesday and Thursday says the value passed through there — it went up smoothly, it didn't teleport. Draw a line only when that sentence is true of your data.

Which means x must be ordered

Time, distance, temperature, dose — something with a real "in between". And matplotlib will not check for you. It joins points in the order you hand them over, so unsorted timestamps produce a scribble that looks like corrupted data:

df = df.sort_values("when")   # before every line chart
ax.plot(df["when"], df["cups"])

The opposite mistake is drawing a line over categories. Five tea flavours have no order and nothing between them, so the segment from plain to ginger claims something that cannot exist. matplotlib draws it anyway. Use bars.

Style

ax.plot(days, delhi,
        color="#66aaf9",
        linewidth=2.5,
        linestyle="--",     # "-"  "--"  ":"  "-."
        marker="o",
        markersize=5,
        alpha=0.9,
        label="Delhi")

Markers mark real observations. With seven points that's information — it's the difference between "measured seven times" and "measured continuously". With seven hundred it's a caterpillar; leave them off, or use markevery=25.

Linestyle over colour when you can. Dashes survive greyscale printing and colour blindness; a red line and a green line don't.

There's also the format-string shorthand — ax.plot(x, y, "r--o"). It's everywhere online and it's fine to read, but write the keywords: you'll know what you meant in a month.

fill_between

The most useful thing to put next to a line is a band:

ax.plot(days, delhi, label="Delhi")
ax.fill_between(days, mumbai, delhi, alpha=0.2)

Confidence intervals, min/max ranges, the gap between two series. Note what it returns — a collection, not a line, so it lands in ax.collections and leaves ax.lines untouched. That trips people up when they go looking for it.

With one argument for the lower bound it fills to zero, and where=delhi > mumbai fills only part of the range — handy for shading recessions, closures, or whichever periods you're calling out.

Reference lines

ax.axhline(np.mean(delhi), linestyle="--", color="#9a9a9a")
ax.axvline("Sat")            # a vertical, at a category or a date
ax.axhspan(60, 80, alpha=0.1)  # a horizontal band

These span the whole axes whatever the limits turn out to be, so they don't need updating when the data changes. A faint mean line turns "here is a wiggle" into "here is the wiggle, and here is normal", which is most of what a reader wants.

Relatives

  • ax.step(x, y, where="post") — when the value holds and then jumps. Prices, inventory, staffing levels.
  • ax.stackplot(x, a, b, c) — several series stacked into a total over time.
  • ax.errorbar(x, y, yerr=e) — points with uncertainty attached.

See it run

The lesson's code, ready to run and to fiddle with.

Putting the kettle on…

Starting up…

Worked example

not graded

Already written and ready to go — press Run to see what it does, then change a number, a column name, anything, and run it again.

tryadding where=np.array(delhi) > 70 to fill_between and seeing what shades.

Press Run — the output appears here.

Your turn

3 exercises. Write the code yourself, then press Check — a nudge and the answer are there if you want them.

Plot delhi as a dashed line with circle markers, then return [linestyle, marker] read back off the line.

your answer

Plot delhi, then shade the gap between mumbai and delhi with fill_between. Return [len(ax.lines), len(ax.collections)] — the point is that the shading is not a line.

your answer

Plot delhi and add a horizontal reference line at its mean. Return the y value that line sits at, read back with float(ax.lines[-1].get_ydata()[0]).

your answer