block by StewartNoyce 9625726

Ancient Histogram

Full Screen

This example displays a histogram from data generated with the Numpy library in Python. Typical code sample:


>>> import numpy as np
>>> count, division = np.histogram(d.price)

One might use a script to generate a number of histograms from a rather involved dataset, and view them later with D3.

Original code from Bostock’s Histogram was modified to 1) read from a JSON file, 2) prepare the displayed data structure, and 3) add a title.

The title is placed with knowledge of the data set. It would be useful to extend the example to place the title in white space given a heuristic.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<!-- 
	original html from bostock #3048450, 
	modified to show histogram data from numpy 
-->
<style>

body {
  font: 10px sans-serif;
}

.bar rect {
  fill: #31a354;
  shape-rendering: crispEdges;
  stroke: #a1d99b;
}

.bar text {
  fill: #fff;
  font-weight: bold;
}

.axis path, .axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.histogram-title {
    font-size: 2em;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>

// A formatter for counts.
var formatCount = d3.format(",.0f");

var margin = {top: 10, right: 30, bottom: 30, left: 30},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

d3.json("histo.json", function(error, histodata) {

    var d, data = [];
    
    // read in histogram data that was generated previously with python numpy
    for (i=0; i<histodata.division.length; i++) {
        d = [];
        d['x'] = parseFloat(histodata.division[i]);
        d['y'] = parseInt(histodata.count[i]);
        data.push(d);
    }
    
    var w = (histodata.division[histodata.division.length-1]-histodata.division[0])/10;

    var x = d3.scale.linear()
        .domain([0, d3.max(data, function(d) { return d.x; })])
        .range([0, width]);
    
    var y = d3.scale.linear()
        .domain([0, d3.max(data, function(d) { return d.y; })])
        .range([height, 0]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");

    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 + ")");

    var bar = svg.selectAll(".bar")
        .data(data)
      .enter().append("g")
        .attr("class", "bar")
        .attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; });

    bar.append("rect")
        .attr("x", 1)
        .attr("width", x(w) - 1)
        .attr("height", function(d) { return height - y(d.y); });

    bar.append("text")
        .attr("dy", ".75em")
        .attr("y", 6)
        .attr("x", x(w) / 2)
        .attr("text-anchor", "middle")
        .text(function(d) { return formatCount(d.y); });

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);
    
    svg.append("text")
        .attr("class", "histogram-title")
        .attr("y", height - 80)
        .attr("x", width)
        .attr("text-anchor", "end")
        .text(histodata.title);
    });

</script>
</body>
</html>

histo.json

{"title": "Marin Home Prices - Fall 2013","count": [ 92, 192,  68,  32,  12,   8,   4,   2,   0,   2],"division": [  "137000.",   "853300.",  "1569600.",  "2285900.",  "3002200.",  "3718500.",        "4434800.",  "5151100.",  "5867400.",  "6583700.",  "7300000." ]}