Public
Edited
Aug 18, 2023
1 star
Insert cell
Insert cell
Insert cell
chart = {
const legend = Plot.plot({
color: {
range: scheme,
transform: ([a, b]) => 3 * a + b,
unknown: "#ccc" // See Valdez-Cordova, Alaska
},
axis: null,
margin: 0,
inset: 18,
width: 106,
height: 106,
style: "overflow: visible;",
marks: [ // Labels for key
Plot.dot(d3.cross([0, 1, 2], [0, 1, 2]), {
x: ([a, b]) => b - a,
y: ([a, b]) => b + a,
symbol: "square",
rotate: 45,
r: 14,
fill: (d) => d,
title: ([a, b]) => `cre${label(a)}\nsvi${label(b)}`,
tip: true
}),
Plot.text(["svi →"], {
frameAnchor: "right",
fontWeight: "bold",
rotate: -45,
dy: 10
}),
Plot.text(["← cre"], {
frameAnchor: "left",
fontWeight: "bold",
rotate: 45,
dy: 10
})
]
});

const color = legend.scale("color");
const index = new Map(data.map(({ fips, ...rest }) => [fips, rest]));
return Plot.plot({
width: 975,
height: 610,
projection: "identity",
color,
marks: [
Plot.geo(
topojson.feature(us, us.objects.counties),
Plot.centroid({
stroke: "white",
strokeWidth: 0.125,
fill: (d) => bivariateClass(index.get(d.id)),
title: (d) => {
const name = `${d.properties.name}, ${states.get(d.id.slice(0, 2)).name}`;
const value = index.get(d.id);
if (!value || (isNaN(value.PRED3_PE) && isNaN(value.RPL_THEME1)))
return `${name}\nno data`;
const [dc, oc] = bivariateClass(value);
return `${name}\n${
isNaN(value.PRED3_PE) ? "No Data" : value.PRED3_PE
} cre${label(dc)}\n${
isNaN(value.RPL_THEME1) ? "No Data" : value.RPL_THEME1
} svi${label(oc)}`;
},
tip: true
})
),
Plot.geo(topojson.mesh(us, us.objects.states, (a, b) => a !== b), {stroke: "white"}),
() => svg`<g transform="translate(835,410)">${legend}`
],
style: "overflow: visible;"
});
}
Insert cell
Insert cell
cre_svi_county.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
data = FileAttachment("cre_svi_county.csv").csv() // Convert to JSON
.then((data) => {
data.forEach((d) => {
d.PRED3_PE = +d.PRED3_PE; // type as numeric
d.RPL_THEME1 = +d.RPL_THEME1;
});
return data;
})
Insert cell
Insert cell
svi_quantiles = d3.scaleQuantile(data.map(d => d.RPL_THEME1), [0, 1, 2]).quantiles()
Insert cell
cre_quantiles = d3.scaleQuantile(data.map(d => d.PRED3_PE), [0, 1, 2]).quantiles()
Insert cell
Insert cell
bivariateClass = {
const c = cre_quantiles;
const s = svi_quantiles;
return (value) => {
const { PRED3_PE: a, RPL_THEME1: b } = value;
return [
isNaN(a) ? a : +(a > c[0]) + (a > c[1]), // If not missing, assign quantile (i.e., 0, 1, or 2) for cre
isNaN(b) ? b : +(b > s[0]) + (b > s[1]) // If not missing, assign quantile (i.e., 0, 1, or 2) for svi
];
};
}
Insert cell
Insert cell
scheme = ["#e8e8e8", "#e4acac", "#c85a5a","#b0d5df", "#ad9ea5", "#985356","#64acbe", "#627f8c", "#574249"]
Insert cell
Insert cell
us = FileAttachment("counties-albers-10m.json").json()
Insert cell
states = new Map(us.objects.states.geometries.map(d => [d.id, d.properties])) // Get state names
Insert cell
Insert cell
labels = ["low", "medium", "high"]
Insert cell
label = i => labels[i] ? ` (${labels[i]})` : ""
Insert cell
index = new Map(data.map(({ fips, ...rest }) => [fips, rest]))
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