Skip to content

Instantly share code, notes, and snippets.

@NPashaP
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NPashaP/ee144af18f0e307d6549 to your computer and use it in GitHub Desktop.
Save NPashaP/ee144af18f0e307d6549 to your computer and use it in GitHub Desktop.
Linear Model

This example first generates a set of random points. Then the space is divided into squares and each square is colored proportional to the log of the minimum of residue for all lines passing through the square. Hovering over a square shows the line with minimum residue for all lines passing through the square.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
circle{
fill:#DE3D71;
}
rect{
stroke:none;
}
line{
stroke:#29342E;
stroke-width:3px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 0, right: 0, bottom: 0, left: 0},
width = 960 - margin.left - margin.right,
height = 580 - margin.top - margin.bottom,
sqsz = 6 // square size in pxl
,rad = 3 // radius of dots
;
function getRandomPoints(){ // generate array of random points
var ret =[]
,n = 80 // number of points to generate
,m = -0.3 // slope of line for sampling
,b = 65 // intercept of line for sampling
,c = 0 // counter for points generated so far.
,w = 5 // perturbation scale
,xmax = width/sqsz -1
,ymax = height/sqsz
;
do {
var x=Math.round(Math.random()*xmax), y=Math.round(m*x+b +(2*Math.random()-1)*w);
if( y>0 && y<ymax ){
ret.push({x:x, y:y});
}
c+=1;
}while(c<n);
return ret;
}
function res(x0, y0){
var sx=d3.sum(points.map(function(d){ return (d.x-x0)*(d.x-x0) }))
,sy=d3.sum(points.map(function(d){ return (d.y-y0)*(d.x-x0) }))
,m = sy/sx
;
return {
m:m
,res:Math.log(d3.sum(points.map(function(d){ var r = d.y-y0 - m*(d.x - x0); return r*r; })))
};
}
var sq = [];
var points = getRandomPoints();
for(var j=0; j< height/sqsz; j++){
for(var i=0; i< width/sqsz; i++){
sq.push({x:i, y:j, s:res(i, j)});
}
}
function moveline(d){
//console.log(d);
svg.select("line").attr("x1",0).attr("y1",d.y*sqsz+d.s.m*(0-d.x*sqsz))
.attr("x2",width).attr("y2",d.y*sqsz+d.s.m*(width-d.x*sqsz));
}
var max=d3.max(sq.map(function(s){ return s.s.res;}))
,min=d3.min(sq.map(function(s){ return s.s.res;}))
;
var color = d3.scale.linear().domain([min, max]).range(["#FFF","#4682b4"]);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.selectAll("rect")
.data(sq)
.enter().append("rect")
.attr("x",function(d){return d.x*sqsz}).attr("y",function(d){return d.y*sqsz})
.attr("width",sqsz).attr("height",sqsz)
.attr("res",function(d){ return d.s.res})
.attr("m",function(d){ return d.s.m})
.style("fill",function(d){ return color((d.s.res))})
.on("mouseover",function(d){ return moveline(d);});
svg.append("line").attr("x1",0).attr("y1",0).attr("x2",0).attr("y2",0);
svg.selectAll("circle")
.data(points)
.enter().append("circle")
.attr("cx",function(d){return (d.x+.5)*sqsz}).attr("cy",function(d){return (d.y+.5)*sqsz})
.attr("r",rad);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment