plot = {
const density = [...kde.density1d(mentalHealthAppCostEffectiveness)];
const nearestQuantilesInDensity = [0.5]
.map((p) => d3.quantile(mentalHealthAppCostEffectiveness, p))
.map((q) => ({
i: d3.bisectCenter(
density.map((d) => d.x),
q
),
q
}))
.map(({ q, i }) => ({ x: q, y: density[i].y }));
return Plot.plot({
y: { ticks: 0, label: "Density Estimate" },
x: {
domain: [
d3.min(mentalHealthAppCostEffectiveness),
d3.max([d3.quantile(mentalHealthAppCostEffectiveness, 0.97), 70])
],
label: "Cost-Effectivess (WELLBYs/US$1000)"
},
color: { legend: true },
height: 256,
width,
marks: [
Plot.areaY(density, { x: "x", y: "y", fillOpacity: 0.1 }),
Plot.lineY(density, { x: "x", y: "y" }),
Plot.ruleY([0]),
Plot.ruleX(
[
{ Name: "GiveDirectly", "Cost-Effectiveness": 8 },
{ Name: "AMF", "Cost-Effectiveness": 70 },
{ Name: "StrongMinds", "Cost-Effectiveness": 17 }
],
{ x: "Cost-Effectiveness", stroke: "Name", tip: true }
),
Plot.ruleX(nearestQuantilesInDensity, {
x: "x",
y2: "y",
strokeDasharray: [5, 3]
}),
Plot.axisX(),
Plot.axisX(
nearestQuantilesInDensity.map(({ x }) => x),
{ textStroke: "#fff", textStrokeWidth: 5 }
),
Plot.crosshairX(density, { x: "x", y: "y" })
]
});
}