Published
Edited
Mar 17, 2021
Importers
29 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
height = 450
Insert cell
w = 300
Insert cell
h = 300
Insert cell
x = d3.scaleLinear().range([0, w])
Insert cell
y = d3.scaleLinear().range([0, h])
Insert cell
mutable p_a = Math.random()
Insert cell
mutable p_b_given_a = Math.random()
Insert cell
mutable p_b_given_not_a = Math.random()
Insert cell
mutable p_b = null
Insert cell
mutable p_a_given_b = null
Insert cell
mutable p_a_given_not_b = null
Insert cell
variables = [
{
name: "P(A)",
concrete: "Sick",
axis: 0,
side: 0,
level: 1,
derived: false,
derivation: () =>
mutable p_b * mutable p_a_given_b +
(1 - mutable p_b) * mutable p_a_given_not_b,
value: function(_) {
return arguments.length ? (mutable p_a = _) : mutable p_a;
}
},
{
name: "P(B|A)",
concrete: "If sick, positive",
axis: 1,
side: 0,
level: 0,
derived: false,
derivation: () => (mutable p_a_given_b * mutable p_b) / mutable p_a,
value: function(_) {
return arguments.length ? (mutable p_b_given_a = _) : mutable p_b_given_a;
}
},
{
name: "P(B|¬A)",
concrete: "If healthy, positive",
axis: 1,
side: 1,
level: 0,
derived: false,
derivation: () =>
((1 - mutable p_a_given_b) * mutable p_b) / (1 - mutable p_a),
value: function(_) {
return arguments.length
? (mutable p_b_given_not_a = _)
: mutable p_b_given_not_a;
}
},
{
name: "P(B)",
concrete: "Test positive",
axis: 1,
side: 0,
level: 1,
derived: true,
derivation: () =>
mutable p_a * mutable p_b_given_a +
(1 - mutable p_a) * mutable p_b_given_not_a,
value: function(_) {
return arguments.length ? (mutable p_b = _) : mutable p_b;
}
},
{
name: "P(A|B)",
concrete: "If positive, sick",
axis: 0,
side: 0,
level: 0,
derived: true,
derivation: () => (mutable p_b_given_a * mutable p_a) / mutable p_b,
value: function(_) {
return arguments.length ? (mutable p_a_given_b = _) : mutable p_a_given_b;
}
},
{
name: "P(A|¬B)",
concrete: "If negative, sick",
axis: 0,
side: 1,
level: 0,
derived: true,
derivation: () =>
((1 - mutable p_b_given_a) * mutable p_a) / (1 - mutable p_b),
value: function(_) {
return arguments.length
? (mutable p_a_given_not_b = _)
: mutable p_a_given_not_b;
}
}
]
Insert cell
areas = [
{
name: "P(A ⋀ B)",
concrete: "True positives",
color: "#c9f6ab",
textColor: "#3e6b21",
value: () => mutable p_a * mutable p_b_given_a,
corners: () =>
variables[0].derived
? [[0, 0], [mutable p_b, mutable p_a_given_b]]
: [[0, 0], [mutable p_b_given_a, mutable p_a]],
coords: () =>
variables[0].derived
? [mutable p_b / 2, mutable p_a_given_b / 2]
: [mutable p_b_given_a / 2, mutable p_a / 2]
},
{
name: "P(A ⋀ ¬B)",
concrete: "False negatives",
color: "#d1dbc9",
textColor: "#435438",
value: () => mutable p_a * (1 - mutable p_b_given_a),
corners: () =>
variables[0].derived
? [[1, 0], [mutable p_b, mutable p_a_given_not_b]]
: [[1, 0], [mutable p_b_given_a, mutable p_a]],
coords: () =>
variables[0].derived
? [(mutable p_b + 1) / 2, mutable p_a_given_not_b / 2]
: [(mutable p_b_given_a + 1) / 2, mutable p_a / 2]
},
{
name: "P(¬A ⋀ B)",
concrete: "False positives",
color: "#ffb2ac",
textColor: "#882620",
value: () => (1 - mutable p_a) * mutable p_b_given_not_a,
corners: () =>
variables[0].derived
? [[0, 1], [mutable p_b, mutable p_a_given_b]]
: [[0, 1], [mutable p_b_given_not_a, mutable p_a]],
coords: () =>
variables[0].derived
? [mutable p_b / 2, (mutable p_a_given_b + 1) / 2]
: [mutable p_b_given_not_a / 2, (mutable p_a + 1) / 2]
},
{
name: "P(¬A ⋀ ¬B)",
concrete: "True negatives",
color: "#f1f1f1",
textColor: "#333333",
value: () => (1 - mutable p_a) * (1 - mutable p_b_given_not_a),
corners: () =>
variables[0].derived
? [[1, 1], [mutable p_b, mutable p_a_given_not_b]]
: [[1, 1], [mutable p_b_given_not_a, mutable p_a]],
coords: () =>
variables[0].derived
? [(mutable p_b + 1) / 2, (mutable p_a_given_not_b + 1) / 2]
: [(mutable p_b_given_not_a + 1) / 2, (mutable p_a + 1) / 2]
}
]
Insert cell
cornersToPath = ([[x0, y0], [x1, y1]]) =>
`M ${x(x0)} ${y(y0)} H ${x(x1)} V ${y(y1)} H ${x(x0)} Z`
Insert cell
function getLineFunctionFromPoints(a, b) {
var m = (b[1] - a[1]) / (b[0] - a[0]);
return x => m * (x - a[0]) + a[1];
}
Insert cell
d3 = require("d3@5")
Insert cell
style = html`<style>

.graphic svg {
display: block;
width: 100%;
height: 100%;
overflow: visible;
}

.graphic rect {
fill: none;
stroke: black;
}

.graphic line.line2 {
stroke: black;
}

.graphic line.varline {
stroke: #ddd;
stroke-dasharray: 2,2;
}

.graphic text {
text-anchor: middle;
font-family: sans-serif;
/*transition: fill .2s;*/
}

.graphic text.derived {
fill: #ddd;
}

.graphic g.area text {
font-size: 12px;
}

.graphic div.overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 2;
pointer-events: none;
cursor: wait;
}

.sens-spec, .sens-spec * {
position: absolute;
font-family: sans-serif;
font-size: .9em;
font-weight: bold;
color: #0274fe;
}

</style>`
Insert cell
_width = Math.min(640, width)
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