Scatter plots

Matplotlib · Essentials · 8 min

Scatter plots are the first look at correlation, clusters and outliers in any dataset.

ax.scatter(x, y) draws one marker per point without connecting them, which is what you want when the order of points means nothing. Its power is that size and color can encode two more variables:

  • s= marker area in points squared, a scalar or one value per point.
  • c= a single color, or an array of numbers mapped through a colormap (cmap="viridis").
  • alpha= transparency; essential when points overlap heavily.
  • edgecolors="white" and linewidths= to separate touching markers.

When c is numeric, scatter returns a PathCollection that knows its color mapping, so fig.colorbar(sc, ax=ax) adds a scale explaining the colors.

Note that s is an area, not a radius: doubling s makes markers look about 1.4 times wider. If you map a variable to s, scale it so the smallest values are still visible.

For a single plain color and thousands of points, ax.plot(x, y, "o", linestyle="none") is noticeably faster than scatter, because it creates one line object instead of a collection with per-point properties. For hundreds of thousands of points, overplotting makes any scatter unreadable; consider alpha, a hexbin or a 2D histogram instead.

Example

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(0)
x = rng.normal(size=200)
y = 2 * x + rng.normal(size=200)
size = rng.uniform(10, 80, size=200)

fig, ax = plt.subplots()
sc = ax.scatter(x, y, s=size, c=y, cmap="viridis", alpha=0.7)
fig.colorbar(sc, ax=ax, label="y value")

print(type(sc).__name__)             # PathCollection
print(sc.get_offsets().shape)        # (200, 2)
print(np.corrcoef(x, y)[0, 1].round(2))  # 0.88 (strong positive)
fig.savefig("scatter.png")

Remember

  • Use scatter when point order has no meaning
  • s sets marker area and c plus cmap maps a variable to color
  • Add fig.colorbar(sc, ax=ax) whenever color encodes numbers

Watch out for

  • Passing a radius-like value to s, which is an area, so sizes look exaggerated.

Check yourself

  1. You want marker color to show a numeric 'temperature' column. Which call is right?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.scatter.html