Skip to content

Instantly share code, notes, and snippets.

@TLecailtel
Last active January 26, 2018 10:55
Show Gist options
  • Save TLecailtel/829fc354be831e30ba2283a55a8d5826 to your computer and use it in GitHub Desktop.
Save TLecailtel/829fc354be831e30ba2283a55a8d5826 to your computer and use it in GitHub Desktop.
Interactive iris regression
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
font-family: sans-serif;
}
.line {
stroke: grey;
stroke-width: 3;
}
.popup {
fill: red;
font-weight: bold;
}
</style>
</head>
<body>
<script>
// Margin setup
var margin = {
top: 20,
right: 20,
bottom: 60,
left: 60
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// Basic SVG canvas
var 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 + ")");
// Each species will have one of this array's colors
var color = d3.scaleOrdinal(d3.schemeCategory10);
// Format to display the coefficients of the regression equation
var format = d3.format(".2f");
// Function to move an element to the foreground
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
// Function to move an element to the background
d3.selection.prototype.moveToBack = function() {
return this.each(function() {
var firstChild = this.parentNode.firstChild;
if (firstChild) {
this.parentNode.insertBefore(this, firstChild);
}
});
};
// Function to give each species its symbol
symbol = function(x){
if (x=="setosa"){return d3.symbolCircle}
else if (x=="versicolor"){return d3.symbolSquare}
else if (x=="virginica"){return d3.symbolTriangle}
};
d3.csv("iris.csv", function(data) {
data.forEach(function(d) {
// Conversion into numbers
d.petal_length = +d.petal_length;
d.petal_width = +d.petal_width;
});
var x = d3.scaleLinear()
.domain([0,d3.max(data, function (d){return d.petal_length})])
.range([0, width]);
var y = d3.scaleLinear()
.domain([0,d3.max(data, function (d){return d.petal_width})])
.range([height, 0]);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
svg.append("g")
.call(d3.axisLeft(y))
// Label of the x-axis
svg.append("text")
.attr("transform",
"translate(" + (width/2) + " ," +
(height + margin.top + 20) + ")")
.attr("class","axis")
.style("text-anchor", "middle")
.text("Petal length");
// Label of the y-axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.attr("class","axis")
.style("text-anchor", "middle")
.text("Petal width");
var g = svg.selectAll("g").data(data).enter().append("g")
.attr("transform", function(d) {
return "translate(" + x(d.petal_length) + "," + y(d.petal_width) + ")"})
.append("path")
.attr("d", d3.symbol().type(function(d) {return symbol(d.species)}))
.style("fill",function(d){return color(d.species)})
.on("mouseover", function(d){
d3.select(this).transition()
.style("fill", "red")
.attr("d", d3.symbol()
.size(200)
.type(function(d) {return symbol(d.species)})
);
var parentNode = d3.select(this.parentNode).moveToFront();
// Show the x value (petal_length)
parentNode.append("text")
.attr("class","popup")
.attr("transform","translate(" + -70 + " ," + -50 + ")")
.text(function(d) {return "x: " + d.petal_length});
// Show the y value (petal_width)
parentNode.append("text")
.attr("class","popup")
.attr("transform","translate(" + -70 + " ," + -30 + ")")
.text(function(d) {return "y: " + d.petal_width});
parentNode.append("text")
.attr("class","popup")
.attr("transform","translate(" + -70 + " ," + -10 + ")")
.text(function(d) {return d.species});
})
.on("mouseout", function(d) {
d3.select(this).transition()
.style("fill", color(d.species))
.attr("d", d3.symbol().type(function(d) {return symbol(d.species)}));
svg.selectAll(".popup").remove();
});;
var length_mean = d3.mean(data, function(d){return d.petal_length});
var width_mean = d3.mean(data, function(d){return d.petal_width});
// Calculate coefficients b0 and b1
var xr = 0;
var yr = 0;
var term1 = 0;
var term2 = 0;
data.forEach(function(d){
xr = d.petal_length - length_mean;
yr = d.petal_width - width_mean;
term1 += xr * yr;
term2 += xr * xr;
})
var b1 = term1 / term2;
var b0 = width_mean - (b1 * length_mean);
// Returns the sign of a number
sign = function(x){return x < 0 ? " - " : " + ";};
// Returns the parameter as a positive number
positive = function(x){return x < 0 ? -x : x;}
// We need two points to draw a line, so we create (x1,y1) and (x2,y2)
var x1 = d3.min(data, function(d){return d.petal_length});
var x2 = d3.max(data, function(d){return d.petal_length});
var y1 = b1 * x1 + b0;
var y2 = b1 * x2 + b0;
var line_points = [[x1,y1],[x2,y2]]
var line = d3.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); });
// The regression line will be in the background
svg.append("path").moveToBack()
.datum(line_points)
.attr("class", "line")
.attr("d", line);
svg.append("text")
.attr("transform", function(d) {
return "translate(" + 40 + "," + 30 + ")"; })
.text("Equation: y = " + format(b1) + "x" + sign(b0) + format(positive(b0)));
});
</script>
</body>
sepal_length sepal_width petal_length petal_width species
5.1 3.5 1.4 0.2 setosa
4.9 3 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
4.6 3.4 1.4 0.3 setosa
5 3.4 1.5 0.2 setosa
4.4 2.9 1.4 0.2 setosa
4.9 3.1 1.5 0.1 setosa
5.4 3.7 1.5 0.2 setosa
4.8 3.4 1.6 0.2 setosa
4.8 3 1.4 0.1 setosa
4.3 3 1.1 0.1 setosa
5.8 4 1.2 0.2 setosa
5.7 4.4 1.5 0.4 setosa
5.4 3.9 1.3 0.4 setosa
5.1 3.5 1.4 0.3 setosa
5.7 3.8 1.7 0.3 setosa
5.1 3.8 1.5 0.3 setosa
5.4 3.4 1.7 0.2 setosa
5.1 3.7 1.5 0.4 setosa
4.6 3.6 1 0.2 setosa
5.1 3.3 1.7 0.5 setosa
4.8 3.4 1.9 0.2 setosa
5 3 1.6 0.2 setosa
5 3.4 1.6 0.4 setosa
5.2 3.5 1.5 0.2 setosa
5.2 3.4 1.4 0.2 setosa
4.7 3.2 1.6 0.2 setosa
4.8 3.1 1.6 0.2 setosa
5.4 3.4 1.5 0.4 setosa
5.2 4.1 1.5 0.1 setosa
5.5 4.2 1.4 0.2 setosa
4.9 3.1 1.5 0.1 setosa
5 3.2 1.2 0.2 setosa
5.5 3.5 1.3 0.2 setosa
4.9 3.1 1.5 0.1 setosa
4.4 3 1.3 0.2 setosa
5.1 3.4 1.5 0.2 setosa
5 3.5 1.3 0.3 setosa
4.5 2.3 1.3 0.3 setosa
4.4 3.2 1.3 0.2 setosa
5 3.5 1.6 0.6 setosa
5.1 3.8 1.9 0.4 setosa
4.8 3 1.4 0.3 setosa
5.1 3.8 1.6 0.2 setosa
4.6 3.2 1.4 0.2 setosa
5.3 3.7 1.5 0.2 setosa
5 3.3 1.4 0.2 setosa
7 3.2 4.7 1.4 versicolor
6.4 3.2 4.5 1.5 versicolor
6.9 3.1 4.9 1.5 versicolor
5.5 2.3 4 1.3 versicolor
6.5 2.8 4.6 1.5 versicolor
5.7 2.8 4.5 1.3 versicolor
6.3 3.3 4.7 1.6 versicolor
4.9 2.4 3.3 1 versicolor
6.6 2.9 4.6 1.3 versicolor
5.2 2.7 3.9 1.4 versicolor
5 2 3.5 1 versicolor
5.9 3 4.2 1.5 versicolor
6 2.2 4 1 versicolor
6.1 2.9 4.7 1.4 versicolor
5.6 2.9 3.6 1.3 versicolor
6.7 3.1 4.4 1.4 versicolor
5.6 3 4.5 1.5 versicolor
5.8 2.7 4.1 1 versicolor
6.2 2.2 4.5 1.5 versicolor
5.6 2.5 3.9 1.1 versicolor
5.9 3.2 4.8 1.8 versicolor
6.1 2.8 4 1.3 versicolor
6.3 2.5 4.9 1.5 versicolor
6.1 2.8 4.7 1.2 versicolor
6.4 2.9 4.3 1.3 versicolor
6.6 3 4.4 1.4 versicolor
6.8 2.8 4.8 1.4 versicolor
6.7 3 5 1.7 versicolor
6 2.9 4.5 1.5 versicolor
5.7 2.6 3.5 1 versicolor
5.5 2.4 3.8 1.1 versicolor
5.5 2.4 3.7 1 versicolor
5.8 2.7 3.9 1.2 versicolor
6 2.7 5.1 1.6 versicolor
5.4 3 4.5 1.5 versicolor
6 3.4 4.5 1.6 versicolor
6.7 3.1 4.7 1.5 versicolor
6.3 2.3 4.4 1.3 versicolor
5.6 3 4.1 1.3 versicolor
5.5 2.5 4 1.3 versicolor
5.5 2.6 4.4 1.2 versicolor
6.1 3 4.6 1.4 versicolor
5.8 2.6 4 1.2 versicolor
5 2.3 3.3 1 versicolor
5.6 2.7 4.2 1.3 versicolor
5.7 3 4.2 1.2 versicolor
5.7 2.9 4.2 1.3 versicolor
6.2 2.9 4.3 1.3 versicolor
5.1 2.5 3 1.1 versicolor
5.7 2.8 4.1 1.3 versicolor
6.3 3.3 6 2.5 virginica
5.8 2.7 5.1 1.9 virginica
7.1 3 5.9 2.1 virginica
6.3 2.9 5.6 1.8 virginica
6.5 3 5.8 2.2 virginica
7.6 3 6.6 2.1 virginica
4.9 2.5 4.5 1.7 virginica
7.3 2.9 6.3 1.8 virginica
6.7 2.5 5.8 1.8 virginica
7.2 3.6 6.1 2.5 virginica
6.5 3.2 5.1 2 virginica
6.4 2.7 5.3 1.9 virginica
6.8 3 5.5 2.1 virginica
5.7 2.5 5 2 virginica
5.8 2.8 5.1 2.4 virginica
6.4 3.2 5.3 2.3 virginica
6.5 3 5.5 1.8 virginica
7.7 3.8 6.7 2.2 virginica
7.7 2.6 6.9 2.3 virginica
6 2.2 5 1.5 virginica
6.9 3.2 5.7 2.3 virginica
5.6 2.8 4.9 2 virginica
7.7 2.8 6.7 2 virginica
6.3 2.7 4.9 1.8 virginica
6.7 3.3 5.7 2.1 virginica
7.2 3.2 6 1.8 virginica
6.2 2.8 4.8 1.8 virginica
6.1 3 4.9 1.8 virginica
6.4 2.8 5.6 2.1 virginica
7.2 3 5.8 1.6 virginica
7.4 2.8 6.1 1.9 virginica
7.9 3.8 6.4 2 virginica
6.4 2.8 5.6 2.2 virginica
6.3 2.8 5.1 1.5 virginica
6.1 2.6 5.6 1.4 virginica
7.7 3 6.1 2.3 virginica
6.3 3.4 5.6 2.4 virginica
6.4 3.1 5.5 1.8 virginica
6 3 4.8 1.8 virginica
6.9 3.1 5.4 2.1 virginica
6.7 3.1 5.6 2.4 virginica
6.9 3.1 5.1 2.3 virginica
5.8 2.7 5.1 1.9 virginica
6.8 3.2 5.9 2.3 virginica
6.7 3.3 5.7 2.5 virginica
6.7 3 5.2 2.3 virginica
6.3 2.5 5 1.9 virginica
6.5 3 5.2 2 virginica
6.2 3.4 5.4 2.3 virginica
5.9 3 5.1 1.8 virginica
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment