Skip to content

Instantly share code, notes, and snippets.

@ix4
Created July 27, 2018 05:16
Show Gist options
  • Save ix4/ee11aab2ff952eac3632ab7cb3abf288 to your computer and use it in GitHub Desktop.
Save ix4/ee11aab2ff952eac3632ab7cb3abf288 to your computer and use it in GitHub Desktop.
2016 U.S. Presidential Election Results
license:gpl-3.0
height:680
border:no
cb_*
topo.json
2016_0_0_2.*
<!DOCTYPE html>
<img src="topo.svg" width="960" height="680">
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
{
"private": true,
"license": "gpl-3.0",
"author": {
"name": "Clay McClure",
"url": "http://daemons.net"
},
"scripts": {
"prepublish": "bash prepublish"
},
"devDependencies": {
"d3-scale": "^1.0.4",
"d3-scale-chromatic": "^1.1.0",
"d3-geo-projection": "^1.2.1",
"d3-dsv": "^1.0.3",
"ndjson-cli": "^0.3.0",
"shapefile": "^0.5.9",
"topojson-server": "^2.0.0",
"topojson-client": "^2.1.0",
"topojson-simplify": "^2.0.0"
}
}
#!/bin/bash
# U.S. Albers
PROJECTION='d3.geoAlbersUsa().scale(1280).translate([480, 340])'
# The state FIPS codes.
STATES="01 02 04 05 06 08 09 10 11 12 13 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 44 45 46 47 48 49 50 51 53 54 55 56"
# The ACS 5-Year Estimate vintage.
YEAR=2015
# The display size.
WIDTH=960
HEIGHT=680
# Download the census tract boundaries.
# Extract the shapefile (.shp) and dBASE (.dbf).
# Download the census tract population estimates.
for STATE in ${STATES}; do
if [ ! -f cb_${YEAR}_${STATE}_county_B01003.json ]; then
curl -o cb_${YEAR}_${STATE}_county_B01003.json \
"http://api.census.gov/data/${YEAR}/acs5?get=B01003_001E&for=county:*&in=state:${STATE}&key=${CENSUS_KEY}"
fi
done
# Construct TopoJSON.
if [ ! -f topo.json ]; then
geo2topo -n \
counties=<(ndjson-join 'd.id' \
<(ndjson-join 'd.id' \
<(sed -e '2d' -e 's/^46113,/46102,/' 2016_0_0_2.csv \
| csv2json -n \
| ndjson-map -r d3=d3-format '{id: d3.format("05d")(d["FIPS"]), margin_pct: (d["Hillary Clinton"] - d["Donald J. Trump"]) / d["Total Vote"]}') \
<(for STATE in ${STATES}; do \
ndjson-cat cb_${YEAR}_${STATE}_county_B01003.json \
| ndjson-split 'd.slice(1)' \
| ndjson-map '{id: d[1] + d[2], population: +d[0]}'; \
done) \
| ndjson-map 'Object.assign(d[0], d[1])') \
<(shp2json -n cb_2015_us_county_500k.shp \
| geoproject -n "${PROJECTION}" \
| ndjson-map 'd.id = d.properties.GEOID, d') \
| ndjson-map 'd[1].properties = {population: d[0].population, margin_pct: d[0].margin_pct}, d[1]' \
| ndjson-map -r d3 -r d3=d3-scale-chromatic 'z = d3.scaleThreshold().domain([-.10, 0, .10]).range(d3.schemeRdBu[4]), d.properties.fill = z(d.properties.margin_pct), d' \
| ndjson-map -r d3 'z = d3.scaleThreshold().domain([100000, 1000000]).range([.25, .50, 1]), d.properties["fill-opacity"] = z(d.properties.population), d') \
| toposimplify -p 1 -f \
| topoquantize 1e5 \
> topo.json
fi
# Convert to SVG
cat \
<(topo2geo -n counties=- < topo.json) \
| geo2svg --stroke=none -n -p 1 -w ${WIDTH} -h ${HEIGHT} \
| sed '$d' \
> topo.svg
# Insert the legend.
tail -n +4 \
< legend.svg \
>> topo.svg
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment