diff --git a/README.md b/README.md index 6daa107..ec90bca 100644 --- a/README.md +++ b/README.md @@ -120,10 +120,10 @@ Calculate the [standard deviation](http://en.wikipedia.org/wiki/Standard_deviati Calculate the value representing the desired [percentile](http://en.wikipedia.org/wiki/Percentile) `(0 < ptile <= 1)`. Uses the Estimation method to interpolate non-member percentiles. -`histogram(vals[, bins])` +`histogram(vals[, bins[, binLimits]])` --- -Build a histogram representing the distribution of the data in the provided number of `bins`. If `bins` is not set, it will choose one based on `Math.sqrt(vals.length)`. Data will look like: +Build a histogram representing the distribution of the data in the provided number of `bins`. If `bins` is not set, it will choose one based on `Math.sqrt(vals.length)`. `binLimits` can be used to define custom min/max edges for the bins (as an array with two numeric values). Data will look like: ``` histogram { values: [ 86, 159, 253, 335, 907, 405, 339, 270, 146, 100 ], diff --git a/stats.js b/stats.js index 66ca458..5cf4230 100644 --- a/stats.js +++ b/stats.js @@ -154,7 +154,7 @@ function percentile(vals, ptile) { return (1 - fract) * vals[int_part] + fract * vals[Math.min(int_part + 1, vals.length - 1)] } -function histogram (vals, bins) { +function histogram(vals, bins, binLimits) { if (vals == null) { return null } @@ -171,8 +171,8 @@ function histogram (vals, bins) { bins = 1 } - var min = vals[0] - var max = vals[vals.length - 1] + var min = binLimits ? binLimits[0] : vals[0] + var max = binLimits ? binLimits[1] : vals[vals.length - 1] if (min === max) { // fudge for non-variant data min = min - 0.5 @@ -182,7 +182,7 @@ function histogram (vals, bins) { var range = (max - min) // make the bins slightly larger by expanding the range about 10% // this helps with dumb floating point stuff - var binWidth = (range + (range * 0.05)) / bins + var binWidth = (range + (range * (binLimits ? 0 : 0.05))) / bins var midpoint = (min + max) / 2 // even bin count, midpoint makes an edge var leftEdge = midpoint - (binWidth * Math.floor(bins / 2)) diff --git a/test/index.js b/test/index.js index cd54fae..2d65a33 100644 --- a/test/index.js +++ b/test/index.js @@ -234,6 +234,14 @@ test('histogram', (t) => { } t.deepEquals(histogram([-100, -53, 10, 100, -22, 0, 0, 1, 3, 44], 20), expect, 'range goes from negative to positive') + expect = { + binLimits: [0, 9], + binWidth: 1.5, + bins: 6, + values: [1, 2, 1, 2, 0, 0], + } + t.deepEquals(histogram([1, 2, 3, 4, 5, 6], 6, [0, 9]), expect, 'custom bin limits') + function diceTest (n, dieString) { var rolls = [] for (var i = 0; i < n; i++) {