How does pedestrian access to retail and public destinations vary across income levels in major US cities? This dashboard overlays Census median household income with H3 hex-binned accessibility scores derived from Foursquare OS Places data.
Income: ACS 5-year estimates (2022), variable B19013_001E. Sentinel values (−666,666,666) cleaned to null before rendering.
Places: Foursquare OS Places, filtered to retail and public destination categories across all 10 cities.
Access scores: For each H3 hex centroid, a KDTree haversine query counts POIs within straight-line travel distance thresholds (5/10/20 min) for pedestrian, bicycle, and auto modes.
Python · GeoPandas · H3 · DuckDB · Tippecanoe · PMTiles · Cloudflare R2 · Mapbox GL JS · GitHub Pages
made by cloonk ʕ·ᴥ·ʔ
Loading city analysis...
Hover any term below for a plain-language explanation.
| Term | What it means |
|---|---|
| Spearman rA number from −1 to +1 measuring how closely two things move together. Here: do higher-income neighborhoods also have better walking access? +1 = perfect match, 0 = no relationship, −1 = opposite. | How strongly income and walk access are correlated. Positive = richer areas have more destinations nearby. |
| p-valueThe probability the result is just random chance. Below 0.05 means the pattern is statistically real — less than 5% chance it's a fluke. | Is the correlation statistically significant? Below 0.05 = yes. |
| Access DesertA hex cell where zero destinations are reachable within the selected travel time. Like a food desert, but for all kinds of retail and services. High % means many neighborhoods have nothing nearby. | Neighborhoods with zero reachable destinations in the selected time window. |
| Walk–Drive GapThe difference between how many destinations you can reach by driving vs walking in the same time. A big gap means the neighborhood is car-dependent — you need a car to access most things. | How many more destinations driving reaches vs walking. High gap = car-dependent area. |
| Gini CoefficientBorrowed from economics where it measures income inequality. Here it measures how evenly walk access is distributed. 0 = every hex has the same access score. 1 = one hex has everything, the rest have nothing. | Inequality of access scores across all hex cells. 0 = perfectly equal, 1 = maximally unequal. |
| Income QuartileHex cells split into four equal groups by the median household income of their Census tract. Q1 = lowest 25% of incomes, Q4 = highest 25%. | Neighborhoods grouped by income: Q1 lowest → Q4 highest. |
| H3 Resolution 9Each hexagon covers about 0.1 square kilometers — roughly the size of two city blocks. Coarser than individual parcels but finer than Census tracts, making it ideal for neighborhood-level access measurement. | Hex cell size: ~174m edge, ~0.1 km². Finer than tracts, coarser than parcels. |
| Detour FactorReal-world walking routes are never straight lines — you follow streets, avoid obstacles, wait for lights. The detour factor (1.4× for pedestrians) inflates straight-line distance to approximate actual travel distance. | Multiplier converting straight-line distance to realistic travel distance (walk = 1.4×). |
| Variable | Definition |
|---|---|
| MHI | Median Household Income, ACS 5-yr 2022 (B19013_001E) |
| Access Score | Count of POIs reachable within selected time + mode |
| Pedestrian speed | 5 km/h · 1.4× detour |
| Bicycle speed | 15 km/h · 1.3× detour |
| Auto speed | 30 km/h · 1.2× detour |
| Source | Dataset | Year |
|---|---|---|
| US Census Bureau | ACS 5-Year Estimates, TIGER/Line Tracts | 2022 |
| Foursquare | OS Places | 2025 |
| H3 | Uber H3 hexagonal grid | — |
Access scores use straight-line distance with detour factor, not network routing. Scores reflect POI density not quality or hours. POI data may be incomplete in lower-density areas.
map.moveLayer('mhi-fill', 'water') inserts the layer below Mapbox's own water layer. Rivers and bays naturally mask tract edges — no clip geometry, no topology errors.backdrop-filter:blur(14px) at 90% opacity. The map bleeds through every panel. You're always reading data against a live spatial context. Glass isn't an aesthetic choice; it's a function of the layered information architecture beneath.Two accent families swap on product mode toggle via body.mode-public class. All values defined as CSS custom properties on :root.
Sequential purple-to-gold ramp. The warm-to-cool direction avoids traffic-light connotations — no moral judgment embedded. Each stop is perceptually equidistant.
Navy-to-acid-yellow. Spectrally separated from the MHI ramp so both gradients are readable when overlaid at partial opacity. Zero-score hexes disappear rather than claiming false data.
:focus-visible rings use var(--accent) at 2px offset — visible against all panel backgrounds.role="application" + aria-label. Toggle pills: aria-pressed. Mode buttons: role="radio" + aria-checked. Hamburger: aria-expanded. Mobile nav: role="dialog".URLSearchParams encodes product, mode, minutes, and cats on every interaction. Deep-linking and browser back/forward restore exact filter state without server sessions.width .5s — non-vestibular. No autonomous or scroll-triggered animation. All map interactions are pointer-driven.