Public
Edited
Apr 3, 2023
Insert cell
Insert cell
Insert cell
numberOfPeople = 48
Insert cell
people = d3.range(numberOfPeople).map(() => Math.floor(Math.random() * 365))
Insert cell
birthdays = d3.rollups(people, arr => arr.length, d => d)
Insert cell
collisions = birthdays.filter(d => d[1] > 1)
Insert cell
Insert cell
sim = (n) => {
const daysInYear = 365; // todo: leap years? 🤪
const people = d3.range(n).map(() => Math.floor(Math.random() * daysInYear));
const birthdays = d3.rollup(
people,
(arr) => arr.length,
(d) => d
);
return d3.range(daysInYear).map((d) => [d, birthdays.get(d) || 0]);
}
Insert cell
sims = d3.range(45, 50).map((x) => [x, d3.range(30).map(() => sim(x))])
Insert cell
simsSummary = sims.flatMap(([x, sims]) =>
d3.cross(d3.range(0, 5), d3.range(0, 5), (y, z) => ({
x,
y,
z,
p: sims.filter(sim => hasCollisionsCum(sim, y, z)).length / sims.length
}))
)
Insert cell
// tests if data has (exactly) y collisions of (exactly) z people
hasCollisions = (data, y, z) => data.filter(d => d[1] === z).length === y
Insert cell
// tests if data has (at least) y collisions of (at least) z people
hasCollisionsCum = (data, y, z) => data.filter(d => d[1] >= z).length >= y
Insert cell
Plot.plot({
color: {
legend: true,
label:
"Probability of having at least that many collisions of at least that many people",
tickFormat: "%",
scheme: "blues"
},
fy: { label: "Number of people in group" },
x: { label: "Number of collisions" },
y: { label: "Number of people in the collision" },
marks: [
Plot.cell(simsSummary, {
fy: "x", // number of people in group
x: "y", //
y: "z",
fill: "p",
title: "p"
})
]
})
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