Created
February 11, 2013 04:58
-
-
Save paul-english/4752760 to your computer and use it in GitHub Desktop.
Some work graphing a few probability distributions using d3.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var probability = { | |
normal: function(x, mean, stddev) { | |
var y = (1 / (stddev * Math.sqrt(2 * Math.PI))) * Math.pow(Math.E, - (Math.pow(x - mean, 2) / (2 * Math.pow(stddev, 2)))); | |
//console.log('normal', x, mean, stddev, y); | |
return y; | |
}, | |
logNormal: function(x, mean, stddev) { | |
var y = (1 / (x * Math.sqrt(2 * Math.PI * Math.pow(stddev, 2)))) * Math.pow(Math.E, - (Math.pow(Math.log(x) - mean, 2) / (2 * Math.pow(stddev, 2)))); | |
//console.log('logNormal', x, mean, stddev, y); | |
y = isFinite(y) ? y : 0; | |
return y; | |
}, | |
erlang: function(x, kappa, lambda) { | |
var y = (Math.pow(lambda, kappa) * Math.pow(x, kappa - 1) * Math.pow(Math.E, - lambda * x)) / probability.factorial(kappa - 1); | |
//console.log('erlang', x, kappa, lambda, y); | |
return y; | |
}, | |
erlangScale: function(x, kappa, scale) { | |
var y = (Math.pow(x, kappa - 1) * Math.pow(Math.E, - x / scale)) / (Math.pow(scale, kappa) * probability.factorial(kappa - 1)); | |
//console.log('erlang scale', x, kappa, scale, y); | |
return y; | |
}, | |
factorial: function(n) { | |
var rval=1; | |
for (var i = 2; i <= n; i++) | |
rval = rval * i; | |
return rval; | |
} | |
}; | |
/////////////////////////// | |
var graph = function(selector) { | |
var margin = {top:20, bottom:30, left:20, right:30}; | |
var setWidth = 100; | |
var setHeight = 100; | |
var width = setWidth - margin.left - margin.right; | |
var height = setHeight - margin.top - margin.bottom; | |
var domain = [0, 1]; | |
var step = 1; | |
var max, min; | |
var paths = []; | |
var graph = d3.select(selector) | |
.append("svg:svg") | |
.attr("width", setWidth) | |
.attr("height", setHeight); | |
var g = graph.append("svg:g").attr("transform", "translate(0,0)"); | |
var x = d3.scale.linear().domain([0, 1]).range([margin.left, width]); | |
var y = d3.scale.linear().domain([0, 1]).range([height, margin.top]); | |
var line = d3.svg.line() | |
.x(function(d,i) {return x(d.x);}) | |
.y(function(d) {return y(d.y);}) | |
.interpolate('basis'); | |
var xAxis = d3.svg.axis().scale(x).tickSize(-height).tickSubdivide(true); | |
var yAxis = d3.svg.axis().scale(y).ticks(4).orient("right"); | |
var chart = function() {} | |
graph.append("svg:g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis); | |
graph.append("svg:g") | |
.attr("class", "y axis") | |
.attr("transform", "translate(" + width + ",0)") | |
.call(yAxis); | |
chart.render = function() { | |
graph.select(".x.axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis); | |
graph.select(".y.axis") | |
.attr("transform", "translate(" + width + ",0)") | |
.call(yAxis); | |
paths.forEach(function(p) { | |
p.path.attr("d", line(p.data)); | |
}); | |
}; | |
chart.width = function(_) { | |
if (!arguments.length) return setWidth; | |
setWidth = _; | |
width = setWidth - margin.left - margin.right; | |
graph.attr("width", setWidth); | |
x.range([margin.left, width]); | |
chart.render(); | |
return chart; | |
}; | |
chart.height = function(_) { | |
if (!arguments.length) return setHeight; | |
setHeight = _; | |
height = setHeight - margin.top - margin.bottom; | |
graph.attr("height", setHeight); | |
y.range([height, margin.top]); | |
chart.render(); | |
return chart; | |
}; | |
chart.x = function(_) { | |
if (!arguments.length) return x; | |
x = _; | |
xAxis.scale(x); | |
return chart; | |
}; | |
chart.y = function(_) { | |
if (!arguments.length) return y; | |
y = _; | |
yAxis.scale(y); | |
return chart; | |
}; | |
chart.domain = function(_) { | |
if (!arguments.length) return domain; | |
domain = _; | |
x.domain(domain); | |
return chart; | |
}; | |
chart.step = function(_) { | |
if (!arguments.length) return step; | |
step = _; | |
return chart; | |
}; | |
chart.line = function() { | |
if (!arguments.length) return; | |
args = Array.prototype.slice.call(arguments, 0); | |
color = args.pop(); | |
fn = args.shift(); | |
data = []; | |
domain = x.domain() | |
for (var i = domain[0]; i <= domain[1]; i += step) { | |
args.unshift(i); | |
data.push({x: i, y: fn.apply(fn, args)}); | |
args.shift(); | |
} | |
var yVals = data.map(function(d) {return d.y;}); | |
if (max !== null) yVals.push(max); | |
if (min !== null) yVals.push(min); | |
max = Math.ceil(d3.max(yVals)); | |
min = Math.floor(d3.min(yVals)); | |
y.domain([min, max]); | |
chart.render(); | |
var path = g.append("svg:path") | |
.attr("class", "line " + fn.name) | |
.attr("d", line(data)) | |
.attr('style', "stroke:" + color); | |
paths.push({path: path, data: data}); | |
return chart; | |
}; | |
return chart; | |
}; | |
var width = 300; | |
var height = 200; | |
// http://en.wikipedia.org/wiki/Normal_distribution | |
graph('#normal').width(width).height(height) | |
.domain([-5, 5]) | |
.step(0.2) | |
.line(probability.normal, 0, 0.2, "blue") | |
.line(probability.normal, 0, 1, "red") | |
.line(probability.normal, 0, 5, "orange") | |
.line(probability.normal, -2, 0.5, "green"); | |
// http://en.wikipedia.org/wiki/Log-normal_distribution | |
graph('#logNormal').width(width).height(height) | |
.domain([0,3]) | |
.step(0.2) | |
.line(probability.logNormal, 0, 1, "blue") | |
.line(probability.logNormal, 0, 0.25, "red") | |
.line(probability.logNormal, 0, 0.5, "green"); | |
// http://en.wikipedia.org/wiki/Erlang_distribution | |
graph('#erlang').width(width).height(height) | |
.domain([0,20]) | |
.step(0.5) | |
.line(probability.erlangScale, 1, 2.0, "red") | |
.line(probability.erlangScale, 2, 2.0, "green") | |
.line(probability.erlangScale, 3, 2.0, "blue") | |
.line(probability.erlangScale, 5, 1.0, "cyan") | |
.line(probability.erlangScale, 9, 0.5, "orange"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment