Public
Edited
Jan 18, 2023
Importers
7 stars
Insert cell
Insert cell
Plot.plot({
inset: 10,
x: {
type: "log",
label: "Population →"
},

marks: [
Plot.arrow(metros, {
x1: "POP_1980",
y1: "R90_10_1980",
x2: "POP_2015",
y2: "R90_10_2015",
filter: "highlight",
bend: true,
stroke: (d) => d.R90_10_2015 - d.R90_10_1980
}),
Plot.text(
metros,
midpoint({
x1: "POP_1980",
y1: "R90_10_1980",
x2: "POP_2015",
y2: "R90_10_2015",
filter: "highlight",
text: "nyt_display",
fill: "currentColor",
stroke: "white",
dy: -6
})
)
]
})
Insert cell
function midpoint({ x1, x2, y1, y2, ...options } = {}) {
const [X, setX] = Plot.column(x2);
const [Y, setY] = Plot.column(y2);
return Plot.transform({ x: X, y: Y, ...options }, function (data, facets) {
const X1 = Plot.valueof(data, x1);
const X2 = Plot.valueof(data, x2);
const Y1 = Plot.valueof(data, y1);
const Y2 = Plot.valueof(data, y2);
setX(Float64Array.from(data, (d, i) => (X1[i] + X2[i]) / 2));
setY(Float64Array.from(data, (d, i) => (Y1[i] + Y2[i]) / 2));
return { data, facets };
});
}
Insert cell
Insert cell
opts = midpoint({
x1: "POP_1980",
y1: "R90_10_1980",
x2: "POP_2015",
y2: "R90_10_2015"
})
Insert cell
Insert cell
Plot.text(
metros,
midpoint({
x1: "POP_1980",
y1: "R90_10_1980",
x2: "POP_2015",
y2: "R90_10_2015",
text: "nyt_display"
})
).initialize().channels
Insert cell
Insert cell
{
const data = metros;
const facets = [d3.range(data.length)]; // facets are ignored in this case
opts.transform(data, facets);
return { x: opts.x.transform(), y: opts.y.transform() };
}
Insert cell
metros = FileAttachment("metros.csv").csv({typed: true})
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