Public
Edited
Mar 7, 2023
2 forks
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const svg = d3.select(DOM.svg(width, height))
.style("width", "60%")
.style("height", "auto")
.style("font", "4.5px sans-serif")
// .style("text.axis-tick-marks", "7px")
;
svg.append("rect") // background
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "pink")
;
// LEGEND
svg.append("line") // horizon
.attr("x1", 150)
.attr("y1", 170)
.attr("x2", 155)
.attr("y2", 170)
.attr("stroke-width", "0.65")
.attr("stroke", "gray")
;
svg.append("circle") // for animated bootstrap mean (red)
.attr("r", radius)
.attr("cx", 150)
.attr("cy", 180)
.attr("fill", "red")
;
svg.append("circle") // for static sample mean (gray)
.attr("r", radius)
.attr("cx", 150)
.attr("cy", 170)
.attr("fill", "gray")
;

svg.append("rect")
.attr("x", 148)
.attr("y", 187.5)
.attr("width", 4)
.attr("height", 4)
.attr("fill", "orange")
;

svg.append("text") // axis tick number
.attr("x", 157)
.attr("y", 171)
.text("sample mean")
svg.append("text") // axis tick number
.attr("x", 157)
.attr("y", 181)
.text("visual bootstrap")
svg.append("text") // axis tick number
.attr("x", 157)
.attr("y", 191)
.text("vb distribution")
// svg.append("g") // y axis
// .attr('class','axis')
// .call(yAxis)
// .attr("transform", "translate(97.5,0)");
svg.append("line") // y axis
.attr("x1", 97.5)
.attr("y1", y(35))
.attr("x2", 97.5)
.attr("y2", y(40))
.attr("stroke-width", "0.25")
.attr("stroke", "black")
;

for (let i=35; i < 41; i++) {
svg.append("line") // axis ticks
.attr("x1", 95.5)
.attr("y1", y(i))
.attr("x2", 97.5)
.attr("y2", y(i))
.attr("stroke-width", "0.25")
.attr("stroke", "black")
;
svg.append("text") // axis tick number
.attr("x", 90)
.attr("y", y(i - 0.2))
.attr("class", "axis-tick-marks")
.text(i)
;
}
svg.append("line") // horizon
.attr("x1", 50)
.attr("y1", y(d3.mean(sugars)))
.attr("x2", 150)
.attr("y2", y(d3.mean(sugars)))
.attr("stroke", "gray")
.attr("stroke-width", "0.5")

;
svg.append("circle") // for animated bootstrap mean (red)
.attr("r", radius)
.attr("cx", 100)
.attr("cy", y(d3.mean(sugars)))
.attr("fill", "red")
.attr("id", "bsc")
;
svg.append("circle") // for static sample mean (gray)
.attr("r", radius)
.attr("cx", 50)
.attr("cy", y(d3.mean(sugars)))
.attr("fill", "gray")
;

// histogram of means of 100,000 bootstrap samples (done in Python)
svg.append("g")
.attr("id", "histo")
.selectAll("rect")
.data(histoD)
.enter()
.append("rect")
.attr("x", 145)
.attr("y", function (d) {return y(d.xl) - histobarHeight})
.attr("width", function (d) {return d.ct / 3000})
.attr("height", histobarHeight)
.attr("fill", "orange")
;
svg.append("text")
.style("font", "12px Source Serif Pro")
.attr("x", 10)
.attr("y", 20)
.text("example: Visual Bootstrap");
svg.append("text")
.style("font", "5px Source Serif Pro")
.attr("x", 12)
.attr("y", 30)
.text("mean of percentage of sugar in breakfast cereal");
// var line = d3.line()
// .x(function(d) { return x((d.x0 + d.x1)/2); })
// .y(function(d) { return y(d.length); })
// .curve(d3.curveCatmullRom.alpha(0.5))
// ;
function bootstrapIt() {
svg.selectAll("#bsc")
.data([d3.mean(sampleWithReplacement(sugars, sugars.length))])
.transition()
.attr("r", radius)
.attr("cx", 100)
.attr("cy", function(d) {return y(d); }) ;
}
if (animate) {setInterval(bootstrapIt, 500)}

return svg.node();
}
Insert cell
// SHOW THE EFFECT OF AN OUTLIER ON THE UNCERTAINTY DISTRIBUTION:
// sugars.push(200)
Insert cell
d3.mean(sampleWithReplacement(sugars, sugars.length))
Insert cell
x = d3.scaleLinear()
.domain(0, width)
.range([0, width])
Insert cell
y = d3.scaleLinear()
.domain([d3.mean(sugars)-padding, d3.mean(sugars)+padding])
.range([height - padding, 0 + padding])
// .range()
// .domain([35, 40])
;
Insert cell
yAxis = d3.axisLeft().scale(y).tickValues([35, 36, 37, 38, 39, 40]);
Insert cell
d3.mean(sampleWithReplacement(sugars, sugars.length))
Insert cell
function genHistoData () {
let histoData = [];
for (var i = 0; i < binsPlacement.length; i++) {
let thisObj = {}
thisObj.ct = binsCount[i]
thisObj.xl = binsPlacement[i]
histoData.push(thisObj)
}
return(histoData)
}
Insert cell
histoD = genHistoData()
Insert cell
// from Python plt.hist(sugars)
// binsCount = [ 1, 8, 10, 12, 18, 17, 16, 12, 4, 2]
binsCount = [37, 616, 5205, 19942, 36469, 31948, 13041, 2490, 244, 10]
Insert cell
// from Python plt.hist(sugars)
// binsPlacement = [31.6 , 32.79, 33.98, 35.17, 36.36, 37.55, 38.74, 39.93, 41.12, 42.31, 43.5]
binsPlacement = [36.539, 36.7586, 36.9782, 37.1978, 37.4174, 37.637, 37.8566, 38.0762, 38.2958, 38.5154, 38.735]
Insert cell
// calculate width of bin bars
binWidth = binsPlacement[2] - binsPlacement[1]
Insert cell
histobarHeight = 2.5
Insert cell
radius = 2
Insert cell
padding = 10
Insert cell
width = 200
Insert cell
height = 200
Insert cell
sampleWithReplacement([3, 2, 1], 3)
Insert cell
function sampleWithReplacement(x, n, randomSource) {
if (x.length === 0) {
return [];
}

// a custom random number source can be provided if you want to use
// a fixed seed or another random number generator, like
// [random-js](https://www.npmjs.org/package/random-js)
randomSource = randomSource || Math.random;

const length = x.length;
const sample = [];

for (let i = 0; i < n; i++) {
const index = Math.floor(randomSource() * length);

sample.push(x[index]);
}

return sample;
}
Insert cell
d3.mean(sugars)
Insert cell
sugars
Insert cell
sugars = data.map(a => a.dat);
Insert cell
data = d3.csv("https://gist.githubusercontent.com"
+ "/aaronxhill/7ead2912c32c0045e0fc1bd6dbe4ba5c"
+ "/raw/cb3ba454728e8fa4856de9802f712a80d6a5cfad"
+ "/cerealsugar.csv")
// https://gist.github.com/aaronxhill/7ead2912c32c0045e0fc1bd6dbe4ba5c/raw/cb3ba454728e8fa4856de9802f712a80d6a5cfad/cerealsugar.csv
// source: https://vincentarelbundock.github.io/Rdatasets/datasets.html
Insert cell
d3 = require("d3@5")
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