Pretty Histogram Bins
by ramnathv
HTML
<script src="//d3js.org/d3.v3.min.js"></script>
JavaScript
vector = [-1.2071,0.2774,1.0844,-2.3457,0.4291,0.5061,-0.5747,-0.5466,-0.5645,-0.89,-0.4772,-0.9984,-0.7763,0.0645,0.9595,-0.1103,-0.511,-0.9112,-0.8372,2.4158,0.1341,-0.4907,-0.4405,0.4596,-0.6937,-1.4482,0.5748,-1.0237,-0.0151,-0.9359,1.1023,-0.4756,-0.7094,-0.5013,-1.6291,-1.1676,-2.18,-1.341,-0.2943,-0.4659,1.4495,-1.0686,-0.8554,-0.2806,-0.9943,-0.9685,-1.1073,-1.252,-0.5238,-0.4968,-1.806,-0.5821,-1.1089,-1.015,-0.1623,0.5631,1.6478,-0.7734,1.6059,-1.1578,0.6566,2.549,-0.0348,-0.6696,-0.0076,1.7771,-1.1386,1.3678,1.3296,0.3365,0.0069,-0.4555,-0.3665,0.6483,2.0703,-0.1534,-1.3907,-0.7236,0.2583,-0.3171,-0.1778,-0.17,-1.3723,-0.1738,0.8502,0.6976,0.55,-0.4027,-0.1916,-1.1945,-0.0532,0.2552,1.706,1.0015,-0.4956,0.3556,-1.1346,0.8782,0.9729,2.1211]
options = {pretty: true}
options.copy = options.copy === undefined ? true : options.copy;
options.pretty = options.pretty === undefined ? true : options.pretty;
var s = vector;
if (options.copy) s = s.slice();
s.sort(function (a, b) { return a - b; });
// TODO: use http://www.austinrochford.com/posts/2013-10-28-median-of-medians.html
// without sorting
function quantile(p) {
var idx = 1 + (s.length - 1) * p,
lo = Math.floor(idx),
hi = Math.ceil(idx),
h = idx - lo;
return (1-h) * s[lo] + h * s[hi];
}
function freedmanDiaconis() {
var iqr = quantile(0.75) - quantile(0.25);
return 2 * iqr * Math.pow(s.length,-1/3);
}
function pretty(x) {
var scale = Math.pow(10, Math.floor(Math.log(x/10) / Math.LN10)),
err = 10 / x * scale;
if (err <= 0.15) scale *= 10;
else if (err <= 0.35) scale *= 5;
else if (err <= 0.75) scale *= 2;
return scale * 10;
}
var h = freedmanDiaconis();
var h = 0.6118361
if (options.pretty) h = pretty(h);
console.log('pretty h is ' + h)
function bucket(d) {
return h * Math.floor(d / h);
}
function tickRange(n) {
var extent = [bucket(s[0]), h + bucket(s[s.length-1])],
buckets = Math.round((extent[1] - extent[0]) / h),
step = buckets > n ?...