Skip to content

Instantly share code, notes, and snippets.

@jameshenegan
Created September 27, 2019 03:30
Show Gist options
  • Save jameshenegan/e86cb616f29b6809f0a3c1b8b305f75f to your computer and use it in GitHub Desktop.
Save jameshenegan/e86cb616f29b6809f0a3c1b8b305f75f to your computer and use it in GitHub Desktop.
Updating Histogram

Updating Histogram

  1. Generate a random sample from a normal distribution.
  2. Create a histogram for the sample.
  3. Generate another random sample.
  4. Update the histogram.
  5. Repeat steps 3-5.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<script src="index.js"></script>
</body>
</html>
class rNorm {
constructor(n, mu, sd) {
// set up properties
this.n = n
this.mu = mu
this.sd = sd
}
twoObs() {
var u = 0, v = 0;
while (u === 0) u = Math.random(); //Converting [0,1) to (0,1)
while (v === 0) v = Math.random();
return (
{
"obs1": Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v),
"obs2": Math.sqrt(-2.0 * Math.log(u)) * Math.sin(2.0 * Math.PI * v)
})
}
sample() {
var obs = {}
for (var i = 0; i < this.n; i = i + 2) {
const tempTwoObs = this.twoObs()
obs[i] = tempTwoObs["obs1"]
obs[i + 1] = tempTwoObs["obs2"]
}
var tempArray = Object.values(obs)
if (this.n % 2 == 1) {
tempArray.pop()
}
tempArray.forEach((value, index) => {
tempArray[index] = this.sd * value + this.mu
})
return tempArray
}
}
const rng = new rNorm(n = 50000, mu = 100, sd = 15);
myData = rng.sample()
const margin = { top: 10, right: 30, bottom: 30, left: 40 },
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
const numBins = 100
const svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// X axis: scale and draw:
const x = d3.scaleLinear()
.domain([rng.mu - 4 * rng.sd, rng.mu + 4 * rng.sd])
.range([0, width]);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
const histogram = d3.histogram()
.value(d => d)
.domain(x.domain())
.thresholds(x.ticks(numBins));
var bins = histogram(myData);
const y = d3.scaleLinear()
.range([height, 0]);
y.domain([0, d3.max(bins, d => d.length)]);
svg.append("g")
.call(d3.axisLeft(y));
svg.selectAll("rect")
.data(bins)
.enter()
.append("rect")
.attr("x", 1)
.attr("transform", d => `translate(${x(d.x0)}, ${y(d.length)})`)
.attr("width", d => ((x(d.x1) - x(d.x0) < 1) ? 0 : (x(d.x1) - x(d.x0) - 1)))
.attr("height", function (d) { return height - y(d.length); })
.style("fill", "#69b3a2")
d3.interval(() => {
myData2 = rng.sample()
bins = histogram(myData2)
svg.selectAll("rect")
.data(bins)
.transition()
.attr("transform", d => `translate(${x(d.x0)}, ${y(d.length)})`)
.attr("width", d => ((x(d.x1) - x(d.x0) < 1) ? 0 : (x(d.x1) - x(d.x0) - 1)))
.attr("height", function (d) { return height - y(d.length); })
.style("fill", "#69b3a2")
}, 100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment