Public
Edited
Feb 22, 2023
Insert cell
md`# GeoVis Assignment 2`
Insert cell
d3 = require("d3@5")
Insert cell
topojson = require("topojson-client@3")
Insert cell
Colorado_counties = FileAttachment("geo_export_1df364d9-8aeb-46ba-9d4d-d864fc4046a5.json").json()
Insert cell
county_features = topojson.feature(Colorado_counties, Colorado_counties.objects.counties_topojson)
Insert cell
csv_data = d3.csvParse(await FileAttachment("counties_colorado_csv.csv").text(),({geonum, pop, white_nh}) => [geonum, +white_nh/+pop])
//percent of white population in Colorado counties
Insert cell
csv_data_objects = Object.assign((d3.csvParse(await FileAttachment("counties_colorado_csv.csv").text(), d3.autoType)).map(({geonum, pop, white_nh}) => ({geonum: +geonum, whitepct: +white_nh/+pop})))
Insert cell
viewof bins = Inputs.range([0, 20], {step: 1, label: "Bins"})
Insert cell
Plot.plot({
marks: [
Plot.rectY(csv_data_objects, Plot.binX({y: "count"}, {x: "whitepct", thresholds: bins})),
Plot.ruleY([0])
]
})
//Looking at the histogram of pecent of white population in Colorado counties it appears to be left skewed.
// In this histogram the X-axis is the percent of white population starting at the lowest value on the left to the highest percent on the right, the Y-axis is the frequency, the amount of counties that fall within that range, for example we can see the highest bin shows 16, meaning 16 counties in Colorado have a white population percentage between %85 - %90. Most of the counties have a percent at %75 or above
//Because my data is so skewed I chose to use 4 classes entering breaks at .5, .7 and .85 to try and distribute the data without having multiple classes with a high amount of data or several classes with little data. In the Natural Breaks I tried 5 classes and that seemed to break up the classes with higher percentages more
Insert cell
whitepct = Array.from(csv_data.values(), d => d[1])
Insert cell
data = Object.assign(new Map(csv_data), {title: ["Percent of White Population In Colorado by County"]})
Insert cell
md`# Linear Scale (Unclassed)`
Insert cell
linear = d3.scaleLinear()
.domain(d3.extent(whitepct))
.range(["#efedf5", "#756bb1"])
//linear could also be labeled as 'Unclassed'
//.domain is the min and max of your data, (d3.extent(whitepct)) will give us the min and max of our data (whitepct) then using the .range() we can assign hex codes or specify colors to display the values with ranging from minimum to maximum
Insert cell
chart(numericSort(whitepct), linear)
Insert cell
md`# Quantile Classification`
Insert cell
quantile = d3.scaleQuantile()
.domain(whitepct)
.range(["#deebf7", "#9ecae1", "#3182bd"])
//.range() based on order, will be ordered small, medium, largest
// number of classes is determined inside .range() using colors to specify
//.domain(whitepct) reads all of our data and not just the minimum and maximum values
Insert cell
chart(numericSort(whitepct), quantile)
Insert cell
md`# Jenks Natural Breaks Classification`
Insert cell
naturalbreaks = simple.ckmeans(whitepct, 5).map(v => v.pop())
//this is where you determine the amount of classes, here you input your data and amount of classes (whitepct, 5)
//above it outputs our 5 natural breaks. the last class being our maximum
Insert cell
jenks = d3
.scaleThreshold()
.domain(naturalbreaks)
.range(["#edf8e9", "#c7e9c0", "#a1d99b","#74c476", "#31a354", '#006d2c']) //colors used, from colorbrewer
//in the .domain we enter (naturalbreaks) to utalize the array data it created above, makes it much cleaner and simplier than manually inputing the values from the generated breaks above
Insert cell
chart(numericSort(whitepct), jenks)
Insert cell
md`# Equal Interval Classification (Quantize)`
Insert cell
d3.extent(whitepct)
//gives me the minimum and maximum values of the data
Insert cell
quantize = d3.scaleQuantize()
.domain([d3.min(whitepct),d3.max(whitepct)])
.range(["#feebe2", "#fbb4b9", "#f768a1","#ae017e"])
//we use the .domain to specify the min and max values of the data (whitepct) and use the range to choose how many classes we want to split into, this will divide the classes into equal intervals
//classes dependent upon the amount of visual varibles in .range([]) here I've used 4 classes using colors from the colorbrewer website
Insert cell
chart(numericSort(whitepct), quantize)
Insert cell
md`# Threshold`
Insert cell
d3.extent(whitepct)
Insert cell
threshold = d3.scaleThreshold()
.domain([0.5, 0.7, 0.85])
.range(["#fee5d9", "#fcae91", "#fb6a4a", "#cb181d"])
//Threshold is used to create a manual classifcation
//.domain() these are the break points for classes, 2 breaks should be 3 classes (or one more class than break)
//the visual variable is defining how many classes we want inside .range()
Insert cell
chart(numericSort(whitepct), threshold)
Insert cell
showScaleGrouping(whitepct, {
scaleQuantile: quantile,
scaleThreshold: threshold,
scaleJenks: jenks,
scaleQuantize: quantize,
scaleQuantizeNice: quantize.copy().nice()
})
Insert cell
md`# Annex`
Insert cell
Insert cell
Insert cell
simple = require("simple-statistics@7.0.7/dist/simple-statistics.min.js")
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more