block by curran b595fde4d771c5784421

Kernel Density Estimation with Science.js

Full Screen

This is a copy of work done by Jason Davies that demonstrates use of science.js. It is posted here simply so it can be studied. The original example code can be found at science.js/examples/kde. Slight modifications were made so it displays well on bl.ocks.org.

web counter

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>LOESS</title>
    <script src="science.v1.min.js"></script>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <style>

      body {
        font: 10px sans-serif;
      }

      path {
        stroke: #000;
        stroke-width: 1.5px;
        fill: none;
      }

    </style>
  </head>
  <body>
    <div id="vis">
    </div>
    <script>
      // Based on //bl.ocks.org/900762 by John Firebaugh
      d3.json("faithful.json", function(faithful) {
        data = faithful;
        var w = 952,
            h = 476,
            x = d3.scale.linear().domain([30, 110]).range([0, w]),
            bins = d3.layout.histogram().frequency(false).bins(x.ticks(60))(data),
            max = d3.max(bins, function(d) { return d.y; }),
            y = d3.scale.linear().domain([0, .1]).range([0, h]),
            kde = science.stats.kde().sample(data);

        var vis = d3.select("body")
          .append("svg")
            .attr("width", w)
            .attr("height", h);

        var bars = vis.selectAll("g.bar")
            .data(bins)
          .enter().append("g")
            .attr("class", "bar")
            .attr("transform", function(d, i) {
              return "translate(" + x(d.x) + "," + (h - y(d.y)) + ")";
            });

        bars.append("rect")
            .attr("fill", "steelblue")
            .attr("width", function(d) { return x(d.dx + 30) - 1; })
            .attr("height", function(d) { return y(d.y); });

        var line = d3.svg.line()
            .x(function(d) { return x(d[0]); })
            .y(function(d) { return h - y(d[1]); });

        vis.selectAll("path")
            .data(d3.values(science.stats.bandwidth))
          .enter().append("path")
            .attr("d", function(h) {
              return line(kde.bandwidth(h)(d3.range(30, 110, .1)));
            });
      });
    </script>
  </body>
</html>

faithful.json

[
  79, 54, 74, 62, 85, 55, 88, 85, 51, 85, 54, 84, 78, 47, 83, 52, 62, 84, 52, 79, 51, 47, 78, 69, 74, 83, 55, 76, 78, 79, 73, 77, 66, 80, 74, 52, 48, 80, 59, 90, 80, 58, 84, 58, 73, 83, 64, 53,
  82, 59, 75, 90, 54, 80, 54, 83, 71, 64, 77, 81, 59, 84, 48, 82, 60, 92, 78, 78, 65, 73, 82, 56, 79, 71, 62, 76, 60, 78, 76, 83, 75, 82, 70, 65, 73, 88, 76, 80, 48, 86, 60, 90, 50, 78, 63, 72,
  84, 75, 51, 82, 62, 88, 49, 83, 81, 47, 84, 52, 86, 81, 75, 59, 89, 79, 59, 81, 50, 85, 59, 87, 53, 69, 77, 56, 88, 81, 45, 82, 55, 90, 45, 83, 56, 89, 46, 82, 51, 86, 53, 79, 81, 60, 82, 77,
  76, 59, 80, 49, 96, 53, 77, 77, 65, 81, 71, 70, 81, 93, 53, 89, 45, 86, 58, 78, 66, 76, 63, 88, 52, 93, 49, 57, 77, 68, 81, 81, 73, 50, 85, 74, 55, 77, 83, 83, 51, 78, 84, 46, 83, 55, 81, 57,
  76, 84, 77, 81, 87, 77, 51, 78, 60, 82, 91, 53, 78, 46, 77, 84, 49, 83, 71, 80, 49, 75, 64, 76, 53, 94, 55, 76, 50, 82, 54, 75, 78, 79, 78, 78, 70, 79, 70, 54, 86, 50, 90, 54, 54, 77, 79, 64,
  75, 47, 86, 63, 85, 82, 57, 82, 67, 74, 54, 83, 73, 73, 88, 80, 71, 83, 56, 79, 78, 84, 58, 83, 43, 60, 75, 81, 46, 90, 46, 74
]