Public
Edited
Apr 29, 2023
3 stars
Insert cell
Insert cell
Insert cell
chart(d3.groups(flips, d => d))
Insert cell
flips = trials(1e3, N);
Insert cell
count = flips.length
Insert cell
mean = d3.mean(flips)
Insert cell
median = d3.median(flips)
Insert cell
mode = arr.mode(flips)
Insert cell
std = d3.deviation(flips)
Insert cell
min = d3.min(flips)
Insert cell
max = d3.max(flips)
Insert cell
N = 1e5
Insert cell
flipsPct = n => {
const f = flips.filter(d => d === n)
return f.length / flips.length * 100;
}
Insert cell
function* chart(data = []) {
const margin = {left: 40, right: 10, top: 10, bottom: 20}
const w = Math.min(640, width) - margin.left - margin.right;
const h = 300 - margin.top - margin.bottom;

const x = d3.scaleBand()
.domain(d3.range(400, 601))
.range([0, w])
const y = d3.scaleLinear()
.domain([0, data.length ? d3.max(data, ([_, entries]) => entries.length) : 1])
.range([h, 0]);
const svg = d3.create("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
const g = svg.append("g")
.attr("transform", `translate(${[margin.left, margin.top]})`)

const yticks = g.append("g")
.attr("transform", `translate(${w})`)
.call(d3.axisLeft(y).tickSize(w).tickFormat(d => ""))
yticks.selectAll("line").attr("stroke", "#eee")
yticks.select(".domain").remove()

const xvals = d3.range(400, 625, 25);
const xticks = g.append("g")
.call(d3.axisBottom(x).tickValues(xvals).tickSize(h).tickFormat(d => ""))
xticks.selectAll("line").attr("stroke", "#eee")
xticks.select(".domain").remove()

g.append("g")
.call(d3.axisLeft(y).tickSizeOuter(0))

g.append("g")
.attr("transform", `translate(0, ${h})`)
.call(d3.axisBottom(x).tickSizeOuter(0).tickValues(xvals))

const bars = g.selectAll(".bar")
.data(data)
.join("rect")
.attr("class", "bar")
.attr("fill", "steelblue")
.attr("stroke", "steelblue")
.attr("x", ([flips]) => x(flips))
.attr("y", ([_, entries]) => y(entries.length))
.attr("width", x.bandwidth())
.attr("height", ([_, entries]) => h - y(entries.length))
yield svg.node()
}
Insert cell
function* trials(trialN = 1000, trialsN = 1000, side = "heads"){
reset;
const data = [];
for (let i = 0; i < trialsN; i++){
const t = trial(trialN);
data.push(d3.groups(t, d => d).find(d => d[0] === side)[1].length)
if (i % 500 === 0) yield data
}
yield data
}
Insert cell
function trial(N = 1000){
const data = []
for (let i = 0; i < N; i++){
data.push(flip())
}
return data;
}
Insert cell
function flip(){
return coin[Math.round(Math.random())]
}
Insert cell
coin = ["heads", "tails"]
Insert cell
arr = require("arraygeous")
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