One Million Americans Per Tile

Hover any tile for its population, area, and the states it spans · full-screen · download the print.
329 tiles, each ≈ 1,000,000 residents (middle half 951k–1,049k). Data: 2020 U.S. Census, Albers projection.

How it's built

  1. Units. Census tract centers of population (~4,000 people each). A finer unit exists — census blocks, often a single city block — but there are ~8 million of them, and the clustering doesn't scale to that many; tracts are the practical floor.
  2. Bucketing. Grow contiguous clusters to a target headcount, then move border tracts to equalise population and gently round the shapes in.
  3. Colour. The fewest colours so no two neighbouring tiles match.

How equal can they be?

The bigger you make each tile, the more exactly equal you can get — every tile averages over more census tracts, so its population lands closer to the target. Above about 150,000 people per tile they're essentially exact; only very small tiles (a few tracts each) leave real slack.

Population band vs target headcount, nationally
Best-case tile population, as a % of its target, across the whole US.

But the map at the top of this page isn't that tight on purpose. Forcing every tile to be exactly a million makes them stretch out into thin, gerrymandered shapes. So the displayed map trades a little equality for rounder tiles: most land within ±5% of a million, and none are allowed past ±10%.

Is there one right map? No.

Re-roll the random seed and you get a different — equally valid — bucketing:

two equally valid bucketings of the US
~6M people per tile, 55 tiles, two random seeds.

The tiles grow from randomly-ordered starting points, and the equalising tweaks run in random order too, so the seed decides where buckets start and how ties break. How much that matters depends on tile size: with thousands of small tiles the constraints pin a near-unique answer; with a few dozen big ones, seeds genuinely diverge.

Partition agreement vs target headcount
Agreement between random seeds at the same target (100% = identical buckets).

Rectangles, not blobs

The map at the top grows blobby regions out of whole Census blocks. There's a completely different way to do it: rectangles. Stop treating blocks as the units — instead assume each block's people are spread evenly across it, then split the country into vertical strips and slice each strip into stacked cells, placing every cut so that each final cell holds a million people. Same rule — equal population per tile — just boxes instead of blobs, and cuts that can run straight through a block instead of only between them. (This is the version Aaron's pavement library actually makes.)

Hover any cell — same info as the map up top. · full-screen

That even-spread assumption is what makes it work: once population is continuous, you can slice it anywhere — a rectangle's edge can run through the middle of a block and still leave exactly a million people on each side. The blobby version can't, because it keeps blocks whole; it can only cut between them, never through one.


Does the seeding strategy matter?

The blob map grows tiles from randomly-ordered starting points. Alex asked whether a smarter seed order would produce rounder, less "gerrymandered" tiles. Three strategies on the same Census data:

Compactness is measured by moment-of-inertia score — (Area²/2π) ÷ Σr² about each tile's centroid. A perfect disk scores 1.0; tendrilly or elongated shapes score lower. (Polsby–Popper, the classic redistricting metric, is staircase-biased on rasters and barely discriminates between strategies, so MOI leads.)

Compactness distribution by seeding strategy
MOI compactness after population-balancing. Dashed line at 0.30 = "gerrymandered" threshold. Density-first is modestly better; recursive bisection is worst.
Tile maps for each seeding strategy
Same data, three strategies. RCB's rectangular slices are visually obvious.

Density-first is mildly better: ~3% higher median compactness, ~15% fewer gerrymandered tiles, and tighter population equality (CV 0.084 vs 0.094). The "Vatican city" prediction also holds in spirit — seeding a dense core first lets it close off as a small self-contained tile before the suburbs claim it.

Recursive bisection has near-perfect equal population (CV < 0.005) but is the least compact strategy: axis-aligned cuts produce elongated rectangles, not blobs. Its win is precision, not shape.

The upshot: seeding order matters a little, not a lot. Switching to density-first would nudge the map toward rounder tiles, but the improvement is incremental — the equalising pass after seeding is the bigger factor in final tile shape.

Why we use three compactness metrics

The seeding analysis above used MOI alone — moment-of-inertia compactness — as the measure of tile shape. But MOI has blind spots: it only measures how spread out pixels are from the centroid, so it penalizes elongation while missing jagged edges and smooth concavities. After looking at which shapes MOI lets through, we added two more metrics. Convex hull ratio catches shapes with deep notches, but is blind to elongation. Polsby-Popper penalizes jagged perimeters, but misses shapes with smooth curved concavities. Each metric sees something the others don't, so we now score every tile on all three and flag tiles that fail any one of them.

The figure below makes this concrete. Each row shows three shapes that all score the same value on that row's metric.

Four rows of three shapes each; each row shows one metric's blind spots — shapes that pass the threshold but still look gerrymandered
MOI = moment-of-inertia compactness · CH = convex hull ratio · PP = Polsby-Popper.
Thresholds: MOI ≥ 0.5, CH ≥ 0.9, PP ≥ 0.5. All three shapes in each row share the same score.

Prior work

Partitioning a place into equal-population pieces is an old idea. The closest relatives are Neil Freeman's Fifty States with Equal Population, the Engaging Data / FlowingData "split the US by population" interactives, Slate's Equal Population Mapper, and capacity-constrained Voronoi / automated-redistricting methods generally. What's different here is the granularity — hundreds of tiles, so it reads as a texture rather than a few regions.