Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active March 8, 2024 10:40
Show Gist options
  • Select an option

  • Save mbostock/fb6c1e5ff700f9713a9dc2f0fd392c35 to your computer and use it in GitHub Desktop.

Select an option

Save mbostock/fb6c1e5ff700f9713a9dc2f0fd392c35 to your computer and use it in GitHub Desktop.

Revisions

  1. mbostock revised this gist Nov 14, 2016. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -11,13 +11,11 @@
    "devDependencies": {
    "d3-array": "^1.0.1",
    "d3-geo-projection": "^1.2.1",
    "d3-scale-chromatic": "^1.1.0",
    "ndjson-cli": "^0.3.0",
    "shapefile": "^0.5.8",
    "topojson": "^2.0.0",
    "topojson-client": "^2.1.0",
    "topojson-simplify": "^2.0.0"
    },
    "dependencies": {
    "d3-scale-chromatic": "^1.1.0"
    }
    }
  2. mbostock revised this gist Nov 14, 2016. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion legend.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    2 changes: 1 addition & 1 deletion topo.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  3. mbostock created this gist Nov 14, 2016.
    3 changes: 3 additions & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    license: gpl-3.0
    height: 1100
    border: no
    3 changes: 3 additions & 0 deletions .gitignore
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    .DS_Store
    node_modules
    cb_*
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    This variation of my [California population density map](/mbostock/39b34968ad5eab65de1d7da81f78bb27) uses [geo2svg](https://github.com/d3/d3-geo-projection/blob/master/README.md#geo2svg) to generate a static choropleth from the command line!
    2 changes: 2 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    <!DOCTYPE html>
    <img src="topo.svg" width="960" height="1100">
    48 changes: 48 additions & 0 deletions legend.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    23 changes: 23 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    {
    "private": true,
    "license": "gpl-3.0",
    "author": {
    "name": "Mike Bostock",
    "url": "https://bost.ocks.org/mike"
    },
    "scripts": {
    "prepublish": "bash prepublish"
    },
    "devDependencies": {
    "d3-array": "^1.0.1",
    "d3-geo-projection": "^1.2.1",
    "ndjson-cli": "^0.3.0",
    "shapefile": "^0.5.8",
    "topojson": "^2.0.0",
    "topojson-client": "^2.1.0",
    "topojson-simplify": "^2.0.0"
    },
    "dependencies": {
    "d3-scale-chromatic": "^1.1.0"
    }
    }
    90 changes: 90 additions & 0 deletions prepublish
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    #!/bin/bash

    # EPSG:3310 California Albers
    PROJECTION='d3.geoAlbers().parallels([34, 40.5]).rotate([120, 0])'

    # The state FIPS code.
    STATE=06

    # The ACS 5-Year Estimate vintage.
    YEAR=2014

    # The display size.
    WIDTH=960
    HEIGHT=1100

    # Download the census block group boundaries.
    # Extract the shapefile (.shp) and dBASE (.dbf).
    if [ ! -f cb_${YEAR}_${STATE}_bg_500k.shp ]; then
    curl -o cb_${YEAR}_${STATE}_bg_500k.zip \
    "http://www2.census.gov/geo/tiger/GENZ${YEAR}/shp/cb_${YEAR}_${STATE}_bg_500k.zip"
    unzip -o \
    cb_${YEAR}_${STATE}_bg_500k.zip \
    cb_${YEAR}_${STATE}_bg_500k.shp \
    cb_${YEAR}_${STATE}_bg_500k.dbf
    fi

    # Download the list of counties.
    if [ ! -f cb_${YEAR}_${STATE}_counties.json ]; then
    curl -o cb_${YEAR}_${STATE}_counties.json \
    "http://api.census.gov/data/${YEAR}/acs5?get=NAME&for=county:*&in=state:${STATE}&key=${CENSUS_KEY}"
    fi

    # Download the census block group population estimates for each county.
    if [ ! -f cb_${YEAR}_${STATE}_bg_B01003.ndjson ]; then
    for COUNTY in $(ndjson-cat cb_${YEAR}_${STATE}_counties.json \
    | ndjson-split \
    | tail -n +2 \
    | ndjson-map 'd[2]' \
    | cut -c 2-4); do
    echo ${COUNTY}
    if [ ! -f cb_${YEAR}_${STATE}_${COUNTY}_bg_B01003.json ]; then
    curl -o cb_${YEAR}_${STATE}_${COUNTY}_bg_B01003.json \
    "http://api.census.gov/data/${YEAR}/acs5?get=B01003_001E&for=block+group:*&in=state:${STATE}+county:${COUNTY}&key=${CENSUS_KEY}"
    fi
    ndjson-cat cb_${YEAR}_${STATE}_${COUNTY}_bg_B01003.json \
    | ndjson-split \
    | tail -n +2 \
    >> cb_${YEAR}_${STATE}_bg_B01003.ndjson
    done
    fi

    # 1. Convert to GeoJSON.
    # 2. Project.
    # 3. Join with the census data.
    # 4. Compute the population density.
    # 5. Simplify.
    # 6. Compute the county borders.
    geo2topo -n \
    blockgroups=<(ndjson-join 'd.id' \
    <(shp2json cb_${YEAR}_${STATE}_bg_500k.shp \
    | geoproject "${PROJECTION}.fitExtent([[10, 10], [${WIDTH} - 10, ${HEIGHT} - 10]], d)" \
    | ndjson-split 'd.features' \
    | ndjson-map 'd.id = d.properties.GEOID.slice(2), d') \
    <(cat cb_${YEAR}_${STATE}_bg_B01003.ndjson \
    | ndjson-map '{id: d[2] + d[3] + d[4], B01003: +d[0]}') \
    | ndjson-map -r d3=d3-array 'd[0].properties = {density: d3.bisect([1, 10, 50, 200, 500, 1000, 2000, 4000], (d[1].B01003 / d[0].properties.ALAND || 0) * 2589975.2356)}, d[0]') \
    | topomerge -k 'd.id.slice(0, 3)' counties=blockgroups \
    | topomerge --mesh -f 'a !== b' counties=counties \
    | topomerge -k 'd.properties.density' blockgroups=blockgroups \
    | toposimplify -p 1 -f \
    > topo.json

    # Convert to SVG (while dropping the last line).
    cat \
    <(topo2geo -n \
    < topo.json blockgroups=- \
    | ndjson-map -r d3=d3-scale-chromatic '(d.properties.title = d.id, d.properties.fill = d3.schemeOrRd[9][d.id], d)') \
    <(topo2geo -n \
    < topo.json counties=- \
    | ndjson-map '(d.properties.stroke = "black", d.properties.strokeOpacity = 0.3, d)') \
    | geo2svg --stroke=none -n -p 1 -w ${WIDTH} -h ${HEIGHT} \
    | sed '$d' \
    > topo.svg

    # Insert the legend.
    tail -n +4 \
    < legend.svg \
    >> topo.svg

    rm topo.json
    Binary file added preview.jpg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    58 changes: 58 additions & 0 deletions topo.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.