Created
July 3, 2013 04:45
-
-
Save kgryte/5915500 to your computer and use it in GitHub Desktop.
Revisions
-
kgryte created this gist
Jul 3, 2013 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,6 @@ Anscombe's Quartet ================== <a href="http://www.d3js.org" target="_blank">D3.js</a> visualization of <a href="http://en.wikipedia.org/wiki/Anscombe's_quartet" target="_blank">Anscombe's Quartet</a>. Each dataset in the quartet is graphed separately along with its linear best fit. While all datasets have the same summary statistics (mean, variance, correlation, linear fit), their structures differ markedly. Anscombe used the quartet in his seminal paper <a href="http://www.jstor.org/stable/2682899" target="_blank">"Graphs in Statistical Analysis"</a> to emphasize the importance of data visualization for exploratory data analysis. Such visualization exploration enables the analyst to make more informed analytical decisions and conclusions. This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,186 @@ [ [ { "x": 10, "y": 8.04 }, { "x": 8, "y": 6.95 }, { "x": 13, "y": 7.58 }, { "x": 9, "y": 8.81 }, { "x": 11, "y": 8.33 }, { "x": 14, "y": 9.96 }, { "x": 6, "y": 7.24 }, { "x": 4, "y": 4.26 }, { "x": 12, "y": 10.84 }, { "x": 7, "y": 4.82 }, { "x": 5, "y": 5.68 } ], [ { "x": 10, "y": 9.14 }, { "x": 8, "y": 8.14 }, { "x": 13, "y": 8.74 }, { "x": 9, "y": 8.77 }, { "x": 11, "y": 9.26 }, { "x": 14, "y": 8.1 }, { "x": 6, "y": 6.13 }, { "x": 4, "y": 3.1 }, { "x": 12, "y": 9.13 }, { "x": 7, "y": 7.26 }, { "x": 5, "y": 4.74 } ], [ { "x": 10, "y": 7.46 }, { "x": 8, "y": 6.77 }, { "x": 13, "y": 12.74 }, { "x": 9, "y": 7.11 }, { "x": 11, "y": 7.81 }, { "x": 14, "y": 8.84 }, { "x": 6, "y": 6.08 }, { "x": 4, "y": 5.39 }, { "x": 12, "y": 8.15 }, { "x": 7, "y": 6.42 }, { "x": 5, "y": 5.73 } ], [ { "x": 8, "y": 6.58 }, { "x": 8, "y": 5.76 }, { "x": 8, "y": 7.71 }, { "x": 8, "y": 8.84 }, { "x": 8, "y": 8.47 }, { "x": 8, "y": 7.04 }, { "x": 8, "y": 5.25 }, { "x": 19, "y": 12.5 }, { "x": 8, "y": 5.56 }, { "x": 8, "y": 7.91 }, { "x": 8, "y": 6.89 } ] ] This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,58 @@ <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- Stylesheets --> <link href='http://fonts.googleapis.com/css?family=Cabin:500' rel='stylesheet' type='text/css'> <link rel="stylesheet" type="text/css" href="reset.css"> <link rel="stylesheet" type="text/css" href="style.css"> <!-- Libraries --> <script type="text/javascript" src="d3.min.js"></script> <!-- Scripts --> <script type="text/javascript" src="script.js"></script> </head> <body> <h1>Anscombe's Quartet</h1> <script type="text/javascript"> var scatter = Chart.scatter(); // Update settings: scatter.xDomain( [3.5, 19] ) .yDomain( [2, 12.5] ) .yTicks( 5 ); // Load the JSON data: d3.json( 'data.json', function( data ) { var figure, width; // For each dataset in 'data', create a figure and graph the dataset along with its linear fit: for (var i = 0; i < data.length; i++) { // Append a new figure to the DOM: figure = d3.select( 'body' ) .append( 'figure' ); // Get the figure width: width = parseInt( figure.style( 'width' ), 10 ); // Update the chart generator settings: scatter.width( width ) .xLabel( 'x' + (i+1) ) .yLabel( 'y' + (i+1) ); // Append the data and generate a new chart: figure.datum( data[i] ) .attr('class', 'chart') .call( scatter ); // Compute the linear fit: scatter.linearFit(); }; // end FOR i }); </script> </body> </html> This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,48 @@ /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,302 @@ /** * * * * * * @author Kristofer Gryte. http://www.kgryte.com * * */ var Chart = {}; Chart.scatter = function() { var margin = {'top': 20, 'right': 20, 'bottom': 40, 'left': 80}, height = 300, width = 760, radius = 5, xLabel = 'x', yLabel = 'y', xTicks, yTicks, xValue = function(d) { return d.x; }, yValue = function(d) { return d.y; }, xScale = d3.scale.linear(), yScale = d3.scale.linear(), xAxis = d3.svg.axis().scale( xScale ).orient( 'bottom' ), yAxis = d3.svg.axis().scale( yScale ).orient( 'left' ), xDomain, yDomain, line = d3.svg.line().x( X ).y( Y ), linearFit, canvas, graph, dataset, circles; function chart( selection ) { selection.each( function( data ) { // Convert data to standard representation; needed for non-deterministic accessors: data = data.map( function(d, i) { return { 'x': xValue.call(data, d, i), 'y': yValue.call(data, d, i) }; }); if (!xDomain) { xDomain = d3.extent( data, function(d) { return d.x; }); }; if (!yDomain) { yDomain = d3.extent( data, function(d) { return d.y; }); }; if (xTicks) { xAxis.ticks( xTicks ); }; if (yTicks) { yAxis.ticks( yTicks ); }; // Update the x-scale: xScale .domain( xDomain ) .range( [0, width - margin.left - margin.right] ); // Update the y-scale: yScale .domain( yDomain ) .range( [height - margin.top - margin.bottom, 0]); // Create the SVG element: canvas = d3.select( this ).append('svg:svg') .attr('width', width) .attr('height', height) .attr('class', 'canvas'); // Create the graph element: graph = canvas.append('svg:g') .attr('class', 'graph') .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); // Create the dataset group: dataset = graph.append('svg:g') .attr('class', 'dataset'); // Create the circle marks: circles = dataset.selectAll('.point') .data( data ) .enter().append('svg:circle') .attr('class', 'point') .attr('cx', function(d) { return X(d);} ) .attr('cy', function(d) { return Y(d);} ) .attr('r', radius ); // Create the axes: graph.append('svg:g') .attr('class', 'x axis') .attr('transform', 'translate(0,' + yScale.range()[0] + ')') .call( xAxis ) .append('svg:text') .attr('y', 40) .attr('x', xScale.range()[1] / 2) .attr('text-anchor', 'middle') .attr('class', 'label') .text( xLabel ); graph.append('svg:g') .attr('class', 'y axis') .call( yAxis ) .append('svg:text') .attr('transform', 'rotate(-90)') .attr('y', -74) .attr('dy', '.71em') .attr('x', -yScale.range()[0] / 2) .attr('text-anchor', 'middle') .attr('class', 'label') .text( yLabel ); }); }; // end FUNCTION chart() // x-accessor: function X(d) { return xScale( d.x ); }; // y-accessor: function Y(d) { return yScale( d.y ); }; // http://en.wikipedia.org/wiki/Simple_linear_regression function linearRegression( data ){ var lr = {}, n = data.length, sum_x = 0, sum_y = 0, sum_xy = 0, sum_xx = 0, sum_yy = 0; for (var i = 0; i < data.length; i++) { sum_x += data[i].x; sum_y += data[i].y; sum_xy += (data[i].x*data[i].y); sum_xx += (data[i].x*data[i].x); sum_yy += (data[i].y*data[i].y); }; var XX = sum_x*sum_x, XY = sum_x*sum_y, YY = sum_y*sum_y, nxy = n*sum_xy, nxx = n*sum_xx, nyy = n*sum_yy; lr['slope'] = (nxy - XY) / (nxx - XX); lr['intercept'] = (sum_y - lr.slope*sum_x) / n; lr['r2'] = Math.pow( (nxy - XY) / Math.sqrt((nxx-XX)*(nyy-YY)), 2); lr['fn'] = function(x) { return this.slope*x + this.intercept; }; return lr; }; // Linear Regression: (best fit line) chart.linearFit = function() { // Initialize variables: var data, _data, fit, domain, x, slope, intercept; // Get the bound data: data = circles.data(); // Perform the linear fit: fit = linearRegression( data ); // Extract the fit statistics: slope = Math.round( fit['slope'] * 10000) / 10000; intercept = Math.round( fit['intercept'] * 10000 ) / 10000; r2 = Math.round( fit['r2'] * 10000 ) / 10000; // Generate the linear prediction based on a set of input values: 'x' domain = xScale.domain(); x = d3.range( domain[0], domain[1]+0.5, 0.5) _data = x.map( function(d, i) { return { 'x': d, 'y': fit['fn']( d ) // evaluate the fit at a given 'x' value }; }); // Generate the path: graph.append('svg:path') .data( [ _data ] ) .attr('class', 'line bestfit') .attr('d', line) .append('svg:title') .text( 'Fit: y = ' + slope + 'x + ' + intercept + ' ; r2 = ' + r2 ); }; // Set/Get: margin chart.margin = function( _ ) { if (!arguments.length) return margin; margin = _; return chart; }; // Set/Get: width chart.width = function( _ ) { if (!arguments.length) return width; width = _; return chart; }; // Set/Get: height chart.height = function( _ ) { if (!arguments.length) return height; height = _; return chart; }; // Set/Get: x chart.x = function( _ ) { if (!arguments.length) return xValue; xValue = _; return chart; }; // Set/Get: y chart.y = function( _ ) { if (!arguments.length) return yValue; yValue = _; return chart; }; // Set/Get: radius chart.radius = function( _ ) { if (!arguments.length) return radius; radius = _; return chart; }; // Set/Get: xLabel chart.xLabel = function( _ ) { if (!arguments.length) return xLabel; xLabel = _; return chart; }; // Set/Get: yLabel chart.yLabel = function( _ ) { if (!arguments.length) return yLabel; yLabel = _; return chart; }; // Set/Get: xDomain chart.xDomain = function( _ ) { if (!arguments.length) return xDomain; xDomain = _; return chart; }; // Set/Get: yDomain chart.yDomain = function( _ ) { if (!arguments.length) return yDomain; yDomain = _; return chart; }; // Set/Get: xTicks chart.xTicks = function( _ ) { if (!arguments.length) return xTicks; xTicks = _; return chart; }; // Set/Get: yTicks chart.yTicks = function( _ ) { if (!arguments.length) return yTicks; yTicks = _; return chart; }; return chart; }; // end FUNCTION scatterChart() This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,63 @@ /* Apply a natural box layout model to all elements */ * { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } body { font-family: 'Cabin', sans-serif; font-size: 14px; font-weight: normal; color: #474747; width: 100%; min-height: 100%; } h1 { width: 70%; margin: 0 auto; margin-top: 20px; margin-bottom: 20px; text-align: center; font-size: 24px; } figure { position: relative; float: left; width: 50%; } .canvas { font-family: 'Cabin', sans-serif; font-size: 14px; fill: #474747; font-weight: normal; } .axis path, .axis line { fill: none; stroke: #aaa; stroke-width: 1px; shape-rendering: crispEdges; } .y.axis path { stroke: none; } .point { fill: rgb(255,166, 0); stroke: rgb(227,121,0); stroke-width: 2px; } .line { fill: none; stroke: steelblue; stroke-width: 2px; }