A graphical toolkit for visualization
Protovis
Overview
Examples
Documentation
Download
Index
« Previous / Next »

Nightingale’s Rose

View full screen.

Florence Nightingale used this rose or coxcomb diagram to emphasize the number of deaths due to “preventible or mitigable zymotic diseases” in the Crimean War. Like Burtin, Nightingale employed a polar bar chart, though Nightingale employed a clever ordering of wedges by value to minimize occlusion. Color encodes the cause of death: blue is disease, red is wounds, and black is uncategorized.

For comparison, see the same data as a stacked area chart, a stacked bar chart, a grouped bar chart and a line chart. Which do you think best shows the data, and why?

Next: Playfair’s Wheat

Source

<html>
  <head>
    <title>Crimean War</title>
    <link type="text/css" rel="stylesheet" href="ex.css?3.2"/>
    <script type="text/javascript" src="../protovis-r3.2.js"></script>
    <script type="text/javascript" src="crimea.js"></script>
    <style type="text/css">
      #fig {
        width: 800px;
        height: 450px;
      }
      #title {
        font: 16px baskerville;
        text-transform: uppercase;
      }
      #caption {
        position: absolute;
        font: oblique 12px baskerville;
        top: 300px;
        left: 25px;
        width: 320px;
      }
      #caption p {
        margin: 0;
        text-indent: 12px;
      }
    </style>
  </head>
  <body><div id="center"><div id="fig">
    <center id="title">
      Diagram <small>of the</small> Causes <small>of</small> Mortality<br>
      <small><small>in the</small> Army <small>of the</small> East</small>
    </center>
    <script type="text/javascript+protovis">

      /* Compute maximum. */
      crimea.forEach(function(d) d.max = Math.max(350, d.wounds, d.other, d.disease));

      /* Scales for radius, angle, and fill. */
      var format = pv.Format.date("%b"),
          radius = pv.Scale.linear(0, 1400).range(0, 275),
          angle = pv.Scale.linear(0, 12).range(Math.PI / 2, 5 * Math.PI / 2),
          fill = pv.colors("lightpink", "darkgray", "lightblue").domain(causes);

      var vis = new pv.Panel()
          .width(800)
          .height(450);

      /* Split the root panel by year. */
      var panel = vis.add(pv.Panel)
          .data([crimea.slice(12), crimea.slice(0, 12)])
          .left(function() this.index * 400);

      /* Add a panel per month, and sort causes by that month's deaths. */
      var wedge = panel.add(pv.Panel)
          .data(function(d) d)
        .add(pv.Wedge)
          .data(function(d) causes.sort(function(a, b) d[b] - d[a]))
          .left(200)
          .top(150)
          .angle(Math.PI / 6)
          .startAngle(function(c, d) angle(d.date.getMonth()))
          .outerRadius(function(c, d) radius(d[c]))
          .fillStyle(fill)
          .strokeStyle(function() this.fillStyle().darker())
          .lineWidth(1);

      /* Add a label using the pre-computed maximum value. */
      wedge.add(pv.Wedge)
          .data(["max"])
          .fillStyle(null)
          .strokeStyle(null)
        .anchor("outer").add(pv.Label)
          .text(function(c, d) format(d.date))
          .textAlign("center")
          .textBaseline("bottom")
          .textAngle(function() this.anchorTarget().midAngle() + Math.PI / 2);

      vis.render();

    </script>
    <div id="caption">
      The Areas of the blue, red, &amp; black wedges are each measured from the
      centre as the common vertex
      <p>The blue wedges measured from the centre of the circle represent area
      for area the deaths from Preventible or Mitigable Zymotic Diseases, the
      red wedges measured from the center the deaths from wounds, &amp; the
      black wedges measured from the center the deaths from all other causes
      <p>In October 1844, &amp; April 1855, the black area coincides with the
      red, in January &amp; February 1856, the blue coincides with the black
      <p>The entire areas may be compared by following the blue, the red &amp;
      the black lines enclosing them.
    </div>
  </div></div></body>
</html>

Data

var causes = ["wounds", "other", "disease"];

var crimea = [
  { date: "4/1854", wounds: 0, other: 110, disease: 110 },
  { date: "5/1854", wounds: 0, other: 95, disease: 105 },
  { date: "6/1854", wounds: 0, other: 40, disease: 95 },
  { date: "7/1854", wounds: 0, other: 140, disease: 520 },
  { date: "8/1854", wounds: 20, other: 150, disease: 800 },
  { date: "9/1854", wounds: 220, other: 230, disease: 740 },
  { date: "10/1854", wounds: 305, other: 310, disease: 600 },
  { date: "11/1854", wounds: 480, other: 290, disease: 820 },
  { date: "12/1854", wounds: 295, other: 310, disease: 1100 },
  { date: "1/1855", wounds: 230, other: 460, disease: 1440 },
  { date: "2/1855", wounds: 180, other: 520, disease: 1270 },
  { date: "3/1855", wounds: 155, other: 350, disease: 935 },
  { date: "4/1855", wounds: 195, other: 195, disease: 560 },
  { date: "5/1855", wounds: 180, other: 155, disease: 550 },
  { date: "6/1855", wounds: 330, other: 130, disease: 650 },
  { date: "7/1855", wounds: 260, other: 130, disease: 430 },
  { date: "8/1855", wounds: 290, other: 110, disease: 490 },
  { date: "9/1855", wounds: 355, other: 100, disease: 290 },
  { date: "10/1855", wounds: 135, other: 95, disease: 245 },
  { date: "11/1855", wounds: 100, other: 140, disease: 325 },
  { date: "12/1855", wounds: 40, other: 120, disease: 215 },
  { date: "1/1856", wounds: 0, other: 160, disease: 160 },
  { date: "2/1856", wounds: 0, other: 100, disease: 100 },
  { date: "3/1856", wounds: 0, other: 125, disease: 90 }
];

(function() {
  var format = pv.Format.date("%m/%y");
  crimea.forEach(function(d) { d.date = format.parse(d.date); });
})();
Copyright 2010 Stanford Visualization Group