Published
Edited
Nov 11, 2021
1 star
Insert cell
# Map challenge
Insert cell
## Source data
Insert cell
Insert cell
cartographers_2019 = d3.csv(
"https://raw.githubusercontent.com/dakvid/30DayMapChallenge/master/data/cartographers.csv",
d => ({ country: d.location, ...d, year: 2019 })
)
Insert cell
days_2020 = d3.csv("https://raw.githubusercontent.com/dakvid/30DayMapChallenge2020/main/data/day_matrix_for_heatmap.csv")
Insert cell
## Merge cartographers
Insert cell
rename = new Map([
["UK", "United Kingdom"],
["LUK", "United Kingdom"],
["USA", "United States of America"],
["Oslo, Norway", "Norway"],
])
Insert cell
cartographers = [
...cartographers_2019,
...cartographers_2020
].map(d => ({ countryName: rename.get(d.country) || d.country, ...d }))
Insert cell
Plot.plot({
width : 300,
marks: [
Plot.barY(cartographers, Plot.groupX({y: "count"}, {x: "year"})),
Plot.ruleY([0])
]
})
Insert cell
## Where are cartographers ?
Insert cell
locatedCartographers = cartographers.filter(({ country }) => country !== "")
Insert cell
countryList = cartographers.map(({ country }) => country)
Insert cell
countryRollup = d3.rollups(cartographers, v => v.length, d => d.countryName, d => d.year)
Insert cell
Insert cell
Insert cell
countryCount = countryRollup
.map(([ country, [count19, count20]]) => ({ country, count19, count20 })) // to handle undefined values
.map(({ country, count19, count20 }) => ({
country,
count2019: getcount(count19),
count2020: getcount(count20),
}))
Insert cell
import {serialize} from "@palewire/saving-csv"
Insert cell
DOM.download(serialize(countryCount), 'countryCount.csv', "Download CSV")
Insert cell
Choropleth(countryCount, {
id: d => d.country, // country name, e.g. Zimbabwe
value: d => d.count2019,
range: d3.interpolateYlGnBu,
domain: countryCountRange,
features: countries,
featureId: d => d.properties.name,
borders: countrymesh,
projection: d3.geoEqualEarth(),
})
Insert cell
chart = Choropleth(countryCount, {
id: d => d.country, // country name, e.g. Zimbabwe
value: d => d.count2020, // health-adjusted life expectancy
range: d3.interpolateYlGnBu,
features: countries,
featureId: d => d.properties.name, // i.e., not ISO 3166-1 numeric
borders: countrymesh,
projection: d3.geoEqualEarth(),
})
Insert cell
import {countries} from "@d3/world-choropleth"
Insert cell
import {countrymesh} from "@d3/world-choropleth"
Insert cell
### Cartographers that are coming back
Insert cell
cartographers_2019_handles = cartographers_2019.map(({ handle }) => handle)
Insert cell
serailcartographers = cartographers
.filter(({ year }) => year === 2020)
.map(c => ({
serial : cartographers_2019_handles.includes(c.handle),
isNew : !cartographers_2019_handles.includes(c.handle),
...c }))
Insert cell
d3.rollups(
serailcartographers.filter(({ isNew }) => isNew),
v => v.length, d => d.countryName
)
Insert cell
domain = [true, false]
Insert cell
textDomain = ["Serial cartographer (here in 2019)", "New in 2020"]
Insert cell
colorscale = ['#03045e', '#0077b6']
Insert cell
Insert cell
Insert cell
## Imports
Insert cell
import {legend} from "@d3/color-legend"
Insert cell
import {Choropleth} from "@d3/choropleth"
Insert cell
## Sources
https://observablehq.com/@d3/world-choropleth
Insert cell
world = FileAttachment("countries-50m.json").json()
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more