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

Scatter plots

Do these two columns move together — and how much can you read into that

ax.scatters=c=alphafig.colorbarax.hexbinnp.corrcoef

Watch it happen

Play it through, or step back and forth yourself.

ax.scatter(temp, cups)one point per row
ax.plot(x, y, "o")the same picture, faster
sc.get_offsets()the (n, 2) array of positions

A scatter asks one question: do these two measurements move together? Every point is one row of your data, placed by two of its columns. Nothing is connected, because nothing lies between one order and the next.

The idea

A scatter answers one question: do these two measurements move together? Every point is one row, placed by two of its columns. Nothing is joined up, because nothing lies between one order and the next.

fig, ax = plt.subplots()
sc = ax.scatter(orders["temp"], orders["cups"])
ax.set_xlabel("temperature (°C)")
ax.set_ylabel("cups sold")

The cloud tilts down: hot days sell less chai. You can put a number on that — np.corrcoef(temp, cups)[0, 1] gives −0.768 — but the picture tells you something the number can't, namely whether that slope is one real trend or two separate clumps that happen to line up. A correlation coefficient cannot tell those apart. Always look before you quote it.

Encoding more columns

A flat chart has two positions to spend, but a scatter can carry two more variables in size and colour:

sc = ax.scatter(temp, cups,
                s=wait,          # size  — a third column
                c=wait,          # colour — a fourth
                cmap="viridis",
                alpha=0.6,
                edgecolors="none")
fig.colorbar(sc, ax=ax, label="wait (s)")

Two things to know about s. It's area, in points squared, not diameter — so a value twice as large makes a marker only about 1.4× wider, and readers systematically under-read the difference. And it's per-point, so passing an array of length n is the whole feature.

When c= gets numbers rather than a colour name, matplotlib runs them through a colormap — and then fig.colorbar() is not optional. Without the key the colours mean nothing.

Overplotting

This is the failure mode that matters. Past a few hundred points the middle of the cloud goes solid, and the solid part is exactly the region you wanted to understand. You can't tell fifty points from five thousand.

ax.scatter(x, y, alpha=0.3, s=12, edgecolors="none")

Transparency restores density: dark means many, pale means few. Past roughly ten thousand points even that saturates, and you switch to binning the plane instead:

ax.hexbin(x, y, gridsize=40, cmap="magma")
ax.hist2d(x, y, bins=50)

scatter or plot?

ax.plot(x, y, "o") draws the same picture and is considerably faster, because every marker is identical — one artist, not a collection. Use plot when all the points look the same, and scatter when size or colour varies per point. That's the whole distinction.

The sentence at the end

Chai sales fall as temperature rises. That is association, not cause — the weather also changes who's out walking and when the cold-drink stall opens. The scatter shows you that two columns move together. Everything after that is your argument, and the chart won't back you up on it.

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.

trysetting alpha=1 and watching the middle of the cloud go solid.

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.

Scatter temp against cups, then return the shape of sc.get_offsets() as a list — the array of point positions matplotlib is holding.

your answer

Scatter temp against cups, sizing each point by wait and setting alpha=0.5. Return [len(sc.get_sizes()), sc.get_alpha()].

your answer

The scatter shows a downward tilt. Put a number on it: return the correlation between temp and cups, rounded to 3 decimal places.

your answer