Density: hexbin & hist2d
A density plot bins many data points into a grid and colors each cell by how many points it holds, revealing where data piles up even when a scatter plot would collapse into one solid blob.
Learn Density: hexbin & hist2d in our free Matplotlib course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Matplotlib course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll build hexagonal density maps with ax.hexbin(), square ones with ax.hist2d(), add a colorbar, tune the grid size and colormap, and learn when density beats a scatter.
ax.hexbin(x, y) tiles the plot with hexagons and colors each one by how many points land inside it. The gridsize argument controls how many hexagons span the width — bigger numbers mean finer detail. Pass a cmap (colormap) to choose the color scheme. Always pair it with a colorbar so the colors mean something.
What you'll see: a roughly circular cloud of hexagons that glow brightest in the middle and fade toward the edges, showing the data piles up near the center. The colorbar on the right tells you how many points each shade represents.
ax.hist2d(x, y) is the two-dimensional version of a histogram. It lays a rectangular grid of square bins over the data and colors each by its count. Set the number of bins with bins= . It returns several values — the counts, the two sets of edges, and the image — and you pass that last image to fig.colorbar() .
What you'll see: a bright diagonal streak running from lower-left to upper-right, made of square cells, showing that x and y rise together. The brightest cells sit along the diagonal where most points fall, and the colorbar maps each shade to a count.
With a few hundred points, a scatter plot is perfect. But push it to tens of thousands and the dots merge into one solid blob — you can't tell a busy region from a packed one. This is overplotting , and density plots are the cure. Put a scatter and a hexbin side by side and the difference is obvious.
What you'll see: on the left, a near-solid gray smear where you can barely guess the shape. On the right, the hexbin clearly shows two bright hot spots — the two clusters — with a colorbar quantifying how dense each one is.
Replace each ___ to draw a hexbin map and attach a colorbar.
You passed the wrong object. For hist2d use the fourth return value (the image), not the counts.
Your gridsize is too large or too small for the data. Try gridsize=30 and adjust until the structure appears.
Pass bins="log" to hexbin (or use a log norm) so a few crowded cells don't wash out everything else.
Plot the same correlated dataset two ways — hexbin on the left, hist2d on the right — each with its own colorbar, so you can judge which binning you prefer.
Lesson complete — you can map dense data!
You built hexagonal and square density maps, tuned gridsize and colormaps, added colorbars, and saw first-hand why density plots reveal structure that an overplotted scatter hides.
🚀 Up next: Stack Plots & Area Charts — show how parts add up over time.
Practice quiz
What does ax.hexbin(x, y) draw?
- A line of best fit
- A grid of hexagons colored by point count
- A pie chart
- A 3D surface
Answer: A grid of hexagons colored by point count. hexbin tiles the area with hexagons and colors each by how many points fall inside.
Which argument controls how many hexagons span the width?
- bins
- width
- gridsize
- hexcount
Answer: gridsize. gridsize sets how many hexagons span the width; bigger means finer detail.
What is the key difference between hexbin and hist2d?
- hexbin uses hexagonal bins; hist2d uses square bins
- hexbin is 3D
- hist2d cannot show density
- They are identical
Answer: hexbin uses hexagonal bins; hist2d uses square bins. Both show 2D density, but hexbin uses hexagons while hist2d uses square bins.
Which argument sets the number of bins for ax.hist2d()?
- gridsize=
- bins=
- nbins=
- cells=
Answer: bins=. ax.hist2d(x, y, bins=40) sets the number of square bins per axis.
ax.hist2d() returns four values. Which one goes to fig.colorbar()?
- The counts
- The x edges
- The y edges
- The image (the fourth value)
Answer: The image (the fourth value). Unpack counts, xedges, yedges, im — pass the image im to fig.colorbar().
How do you add a colorbar to a hexbin plot?
- fig.colorbar(hb, ax=ax)
- ax.colorbar(hb)
- plt.legend(hb)
- hb.colorbar()
Answer: fig.colorbar(hb, ax=ax). Capture hb = ax.hexbin(...) and pass it to fig.colorbar(hb, ax=ax).
When does a density plot beat a scatter plot?
- For a few hundred points
- When so many points overlap that a scatter becomes a solid blob
- For categorical data
- For a single point
Answer: When so many points overlap that a scatter becomes a solid blob. Density plots reveal structure when overplotting turns a scatter into a blob.
What problem do hexbin and hist2d solve?
- Missing data
- Overplotting of dense scatter points
- Wrong axis labels
- Slow rendering of lines
Answer: Overplotting of dense scatter points. They cure overplotting by binning many points into colored cells.
Why do hexagonal bins often look smoother than square bins?
- They are larger
- Hexagons tile more evenly and avoid square-corner artifacts
- They use more colors
- They ignore outliers
Answer: Hexagons tile more evenly and avoid square-corner artifacts. Hexagons tile more evenly than squares, avoiding the blocky corners of square bins.
Which keeps a few crowded cells from washing out the rest in hexbin?
- gridsize=1
- bins='log' (or a log norm)
- alpha=0
- cmap='gray'
Answer: bins='log' (or a log norm). Passing bins='log' (or a log norm) compresses the scale so dense cells don't dominate.