Published
Edited
Feb 14, 2021
2 forks
Importers
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof P = text({ title: 'Desired P' })
Insert cell
Insert cell
// ZScore = {
// let div = d3.create('div');
// let result;
// if (P === 0) {
// result = -Infinity;
// } else if (parseFloat(P) && !isNaN(P)) {
// if (P == 1) {
// result = Infinity;
// } else if (P < 0 || P > 1) {
// result = NaN;
// } else {
// result = Math.sqrt(2) * erfi(2 * P - 1);
// }
// } else {
// result = '';
// }
// if (!(result === '')) {
// div.append(() => tex`Z= ${result}`);
// }
// return div.node();
// }
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function normal_pdf(t) {
return Math.exp((-t * t) / 2) / Math.sqrt(2 * Math.PI);
}
Insert cell
// ss.inverseErrorFunction does not seem to be too accurate.
// Here's an implementation based on Newton's method.
function erfi(y) {
let sqrtPiOver2 = Math.sqrt(Math.PI) / 2;
if (y == 0) {
return 0;
} else if (y == 1) {
return Infinity;
} else if (y == -1) {
return -Infinity;
} else if (Math.abs(y) > 1) {
return NaN;
} else {
let x = 0.;
for (let i = 0; i < 8; i++) {
x = x - sqrtPiOver2 * Math.exp(x * x) * (ss.errorFunction(x) - y);
}
return x;
}
}
Insert cell
function normal_pic(z1, z2, size) {
let width, height;
if (size) {
width = size;
height = size / 2;
} else {
width = 400;
height = 200;
}
let pad = 5;
let div = d3
.create('div')
.attr('class', 'pic')
.style('width', `${width}px`)
.style('height', `${height + 40}px`)
.style('text-align', 'center');

let pic_container = div
.append('div')
.style('width', `${width + 1}px`)
.style('height', `${height + 1}px`);
let pic = pic_container
.append('svg')
.attr('width', width)
.attr('height', height)
.style('background-color', 'white');

let xmin = -3.4;
let xmax = 3.4;
let ymin = -0.05;
let ymax = 0.5;
let x_scale = d3
.scaleLinear()
.domain([xmin, xmax])
.range([pad, width - pad]);
let y_scale = d3
.scaleLinear()
.domain([ymin, ymax])
.range([height - pad, pad]);
let pts_to_path = d3
.line()
.x(function(d) {
return x_scale(d[0]);
})
.y(function(d) {
return y_scale(d[1]);
});

let dx = 0.01;
let fill_pts;
if (!(isNaN(parseFloat(z1)) || isNaN(parseFloat(z2)))) {
let Z1, Z2;
if (z1 < xmin) {
Z1 = xmin;
} else {
Z1 = z1;
}
if (z1 > xmax) {
Z1 = xmax;
} else {
Z1 = z1;
}
if (z1 === -Infinity) {
Z1 = -4;
}
if (z2 < xmin) {
Z2 = xmin;
} else {
Z2 = z2;
}
if (z2 > xmax) {
Z2 = xmax;
} else {
Z2 = z2;
}
fill_pts = d3.range(Z1, Z2, dx).map(x => [x, normal_pdf(x)]);
fill_pts = [[Z1, 0]].concat(fill_pts).concat([[Z2, 0]]);
pic
.append('path')
.attr('class', 'fill')
.attr('d', pts_to_path(fill_pts))
.attr('stroke', 'none')
.attr('fill', 'lightblue');
}
pic
.append('line')
.attr('x1', x_scale(xmin))
.attr('x2', x_scale(xmax))
.attr('y1', y_scale(0))
.attr('y2', y_scale(0))
.attr('stroke', 'black');
pic
.append('line')
.attr('x1', x_scale(0))
.attr('x2', x_scale(0))
.attr('y1', y_scale(ymin))
.attr('y2', y_scale(ymax))
.attr('stroke', 'black');
let x_ticks = [-3, -2, -1, 1, 2, 3];
pic
.selectAll('line.xtick')
.data(x_ticks)
.join('line')
.attr('class', 'xtick')
.attr('x1', x => x_scale(x))
.attr('x2', x => x_scale(x))
.attr('y1', y_scale(0))
.attr('y2', y_scale(ymin / 3))
.attr('stroke', 'black');
pic
.selectAll('text.xtick')
.data(x_ticks)
.join('text')
.attr('class', 'xtick')
.attr('x', x => x_scale(x) - width / 100)
.attr('y', y_scale(1.05 * ymin))
.text(x => x);

let pts = d3.range(xmin, xmax + dx, dx).map(x => [x, normal_pdf(x)]);
console.log([xmin, xmax, dx]);
pic
.append('path')
.attr('class', 'curve')
.attr('d', pts_to_path(pts))
.attr('stroke', 'black')
.attr('stroke-width', 2.5)
.attr('fill', 'none');

if (!isNaN(parseFloat(z2))) {
let p, tex_string;
if (z1 === -Infinity) {
p = 0.5 + 0.5 * ss.errorFunction(z2 / Math.sqrt(2));
tex_string = `P(Z<${ff(z2)})`;
} else {
p =
.5 *
(ss.errorFunction(z2 / Math.sqrt(2)) -
ss.errorFunction(z1 / Math.sqrt(2)));
tex_string = `P(${ff(z1)}<Z<${ff(z2)})`;
}
div.append(() => tex`${tex_string} \approx ${ff(p)}`);
}

return div.node();
}
Insert cell
ff = d3.format('0.6~f')
Insert cell
Insert cell
ss = require('simple-statistics')
Insert cell
d3 = require('d3@6')
Insert cell
import { pic } from '@mcmcclur/simple-normal-table'
Insert cell
import { text } from "@jashkenas/inputs"
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