Public
Edited
May 8
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
format = d => `${d}%`
Insert cell
Insert cell
counties = FileAttachment("Projected_US_Counties.json").json()
Insert cell
counties_features = topojson.feature(counties, counties.objects.Projected_US_Counties)
Insert cell
2.1 Join
- The attributes for all of the counties within the US are joined with the values of percent of white population from the CSV. The join is based off of "GISJOIN" which is a unique attribute. With these two files joined together, we are able to display on the map what percent of the population is white within each county in the US. GISJOIN is the main key that puts the data together, but all of the values are based on white population divided by total population, seen in the code below, as I normalized it in the first assignment.
Insert cell
csv_data = d3.csvParse(await FileAttachment("USRace.csv").text(),({Total, WhtAlone, GISJOIN}) => [GISJOIN, +WhtAlone/Total])
Insert cell
data = Object.assign(new Map(csv_data), {title: "Percent White in Census 2020"})
Insert cell
data.get(19005)
Insert cell
pct_wht = Array.from(csv_data.values(), d => d[1])
Insert cell
2.2 Mapping Values to Colors
- In the code below, the number of classes is defined, as well as each color for each of the classes. It says Array(5), so there are 5 different classes and 5 different colors that will represent the data. I chose a color scheme from ColorBrewer that was based on a single hue of blue with varying lightness. Smaller values appear lighter, and higher values have a greater hue.
- Nested functions are basically functions that rely on how a function is defined elsewhere within the code. For example, the line two lines down that says "naturalbreaks =" relies on how my variable, "pct_wht" is defined as well as how my color scheme "blue" is defined, which I defined on the line above. Having nested functions makes it so that all of your lines are working together and connected.
Insert cell
blue = [d3.color("#f1eef6"), d3.color("#bdc9e1"), d3.color("#74a9cf"), d3.color("#2b8cbe"),d3.color("#045a8d")]
Insert cell
naturalbreaks = simple.ckmeans(pct_wht, blue.length).map(v => v.pop())
Insert cell
//more information on sequential scales: https://observablehq.com/@d3/sequential-scales
// color = d3.scaleSequentialQuantile([...data.values()], d3.interpolateBlues)

// color = d3.scaleQuantile()
// .domain(med_age)
// .range()

color = d3.scaleThreshold()
.domain(naturalbreaks)
.range(blue)
Insert cell
width = 975
Insert cell
height = 610
Insert cell
margin = 100
Insert cell
2.3 Polygon Styling
- Within Observable, you can define the parameters of the map so they are appealing to the eye. In the lines above, height, width, and margin are defined. These are defining how tall and wide the map will be and how far from the border the map will be. Depending on what you are visualizing, this can help you better communicate your data. Below the map, I changed the stroke width for the county boundaries. I changed it to 0.1 because I have a larger area to display than just the state of Iowa. I also changed the color to white to contrast with the dark blue that dominates my map.
Insert cell
//Rotate the map sets the longitude of origin for our UTM Zone 15N projection.
//projection = d3.geoAlbers().rotate([94,0]).fitExtent([[80, 80], [width, height]], counties);
//d3 reference for projections: https://d3js.org/d3-geo

//use the following url for specific projection settings: https://github.com/veltman/d3-stateplane
//Use this code to set up the map projection (if different than geographic projection)

projection = d3.geoAlbersUsa().fitExtent([[margin, margin], [width - margin, height - margin]], counties_features)

//projection = d3.geoMercator().fitExtent([[margin, margin], [width - margin, height - margin]], counties)
Insert cell
//Using a path generator to project geometry onto the map
path = d3.geoPath().projection(projection);
Insert cell
2.4 Legend
- In the code above, I defined all the parameters for my legend. For color, the value that appears is coming from how I defined color in an earlier function. The code pulls from earlier code, so that natural breaks is the classification, and the blue color scheme is used. The title pulls from how I defined the title for my data and is displayed above the legend. The width defines how wide the legend is, and the tick format defines how the tick marks on the legend will be separated. I changed this to ".1%" because I am visualizing a percentage.
Insert cell
2.5 Mouse Over
- When you move your mouse over a certain county, it will tell you the percent of the population within the county that is white. This is able to be displayed because I joined the counties json with the values for race from my CSV, and we are able to visualize it for the whole country, but also at the county level if you move your mouse over a given county.
Insert cell
2.6 SVG
- SVG stands for scalable vector graphics, and basically is code within the notebook that determines the image that we see. SVG determined the parameters for the map and is responsible for how it appears above. SVG is used to create the choropleth map as a whole, to create the legend, and what data is displayed on the map, and how. This function is nested and relies on how I defined the data within the code earlier. For example, it needs to understand how my colors are defined in order to display them on the map.
Insert cell
data.get(19005)
Insert cell
color(data.get(19005))
Insert cell
color(40)
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