Programming Tips

Clam Demography

An example from a study of clam populations shows how Mathematica can help scientists who wish to view large data sets in imaginative ways.

by 
Stan Wagon
Macalester College
wagon@macalstr.edu

Mathematica in Education
Vol.3 No.3
Summer 1994
(c) TELOS/Springer-Verlag

This is the inaugural edition of a regular column that will discuss programming issues that arise when Mathematica is used to elucidate topics in the undergraduate curriculum. Suggestions for future columns may be sent to the columnist at wagon@macalstr.edu.

Demographers study populations. So do some biologists. The former use a special sort of chart to graph the age distribution of a population. My colleague Dan Hornbach, who, along with his students, carries out research on clam populations in Minnesota lakes, wanted to use the demographers' method of charting a population. This method calls for a stacked series of rectangles of the same height, with width denoting the percentage of the population that lies in a specific age group (demographers also split the rectangle along a vertical center line with the two sides representing the male/female split; but clams are hemaphrodites). Apparently, none of the dozens of general-purpose graphics packages available to the scientific community allows for this sort of chart. Mathematica makes it is easy to custom-design just about any sort of chart, and it took only a few minutes to do exactly what Hornbach wanted.

The desired output is shown in Figure 1, which appeared in [1]. The shading represents the size of the sample collected on a given day, as indicated in the legend.

Figure 1.   A chart of clam-length for samples taken from a Minnesota lake over a 15-month period; the shading indicates the sample size. When it finally warms up in Minnesota in May the clams warm up enough to grow. By December 1985 few clams were collected and no adults (i.e., no large clams) were found. This followed a period of house construction along the lakeshore and the population went through a major crash. They have recovered somewhat by now.

Mathematica can be useful to scientists who wish to look at data in slightly, or radically, nonstandard ways. In fact, there is no question that imaginative views of data can lead to important new results (for a fascinating example relating DNA to the fractal mathematics of the Sierpinski gasket, see [2, 3, 4]). Thus we present this example not only for those interested in populations, but as a general exhortation to think imaginatively when it comes to visualizing large data sets.

In the clam example we have data of the following form.

data = {
 {256, 1.4, 0.016, 125}, {256, 1.5, 0.152, 125}, {256, 1.6, 0.312, 125}, 
 {256, 1.7, 0.272, 125}, {256, 1.8, 0.136, 125}, {256, 1.9, 0.016, 125}, 
 {256,   2, 0.016, 125}, {256, 2.4, 0.008, 125}, {256, 2.5, 0.008, 125}, 
 {256, 2.7, 0.008, 125}, {256, 2.9, 0.008, 125}, {256,   3, 0.008, 125}, 
 {256, 3.3, 0.008, 125}, {256, 3.7, 0.008, 125}, {256,   4, 0.008, 125}, 
 {256, 5.6, 0.008, 125}, {256, 7.7, 0.008, 125}, 
 {283, 1.1, 0.0034,881}, {283, 1.2, 0.015, 881}, 
 {283, 1.3, 0.0568,881}, {283, 1.4, 0.151, 881},  
        (* plus hundreds more..  *)

Full Data Set

(* day of year, length, fraction, number in sample *)


data = {
  {256, 1.4, 0.016, 125}, {256, 1.5, 0.152, 125}, 
  {256, 1.6, 0.312, 125}, {256, 1.7, 0.272, 125}, 
  {256, 1.8, 0.136, 125}, {256, 1.9, 0.016, 125}, 
  {256, 2, 0.016, 125}, {256, 2.4, 0.008, 125}, 
  {256, 2.5, 0.008, 125}, {256, 2.7, 0.008, 125}, 
  {256, 2.9, 0.008, 125}, {256, 3, 0.008, 125}, 
  {256, 3.3, 0.008, 125}, {256, 3.7, 0.008, 125}, 
  {256, 4, 0.008, 125}, {256, 5.6, 0.008, 125}, 
  {256, 7.7, 0.008, 125}, {283, 1.1, 0.00340522, 881}, 
  {283, 1.2, 0.014756, 881}, {283, 1.3, 0.0567537, 881}, 
  {283, 1.4, 0.150965, 881}, {283, 1.5, 0.329171, 881}, 
  {283, 1.6, 0.238365, 881}, {283, 1.7, 0.111237, 881}, 
  {283, 1.8, 0.0215664, 881}, {283, 1.9, 0.00681044, 881}, 
  {283, 2, 0.00113507, 881}, {283, 2.1, 0.00227015, 881}, 
  {283, 2.2, 0.0045403, 881}, {283, 2.3, 0.00340522, 881}, 
  {283, 2.4, 0.00113507, 881}, {283, 2.5, 0.0045403, 881}, 
  {283, 2.6, 0.00113507, 881}, {283, 2.7, 0.00113507, 881}, 
  {283, 2.8, 0.00681044, 881}, {283, 2.9, 0.00340522, 881}, 
  {283, 3, 0.00567537, 881}, {283, 3.2, 0.00113507, 881}, 
  {283, 3.3, 0.0045403, 881}, {283, 3.4, 0.00227015, 881}, 
  {283, 3.5, 0.00567537, 881}, {283, 3.6, 0.00113507, 881}, 
  {283, 3.7, 0.00113507, 881}, {283, 3.8, 0.00227015, 881}, 
  {283, 3.9, 0.00340522, 881}, {283, 4, 0.00340522, 881}, 
  {283, 4.1, 0.00113507, 881}, {283, 4.2, 0.00113507, 881}, 
  {283, 4.5, 0.00227015, 881}, {283, 4.7, 0.00113507, 881}, 
  {283, 4.8, 0.00113507, 881}, {296, 1.3, 0.0178571, 112}, 
  {296, 1.4, 0.0267857, 112}, {296, 1.5, 0.285714, 112}, 
  {296, 1.6, 0.285714, 112}, {296, 1.7, 0.276786, 112}, 
  {296, 1.8, 0.0357143, 112}, {296, 2.9, 0.00892857, 112}, 
  {296, 3, 0.00892857, 112}, {296, 3.8, 0.00892857, 112}, 
  {296, 4, 0.0267857, 112}, {296, 6.9, 0.00892857, 112}, 
  {296, 7.4, 0.00892857, 112}, {317, 1.3, 0.03, 200}, 
  {317, 1.4, 0.055, 200}, {317, 1.5, 0.335, 200}, 
  {317, 1.6, 0.285, 200}, {317, 1.7, 0.2, 200}, 
  {317, 1.8, 0.055, 200}, {317, 2, 0.005, 200}, 
  {317, 2.3, 0.005, 200}, {317, 2.6, 0.005, 200}, 
  {317, 2.8, 0.005, 200}, {317, 3.5, 0.01, 200}, 
  {317, 3.8, 0.005, 200}, {317, 5.5, 0.005, 200}, 
  {352, 1.3, 0.00980392, 102}, {352, 1.4, 0.0686275, 102}, 
  {352, 1.5, 0.303922, 102}, {352, 1.6, 0.313725, 102}, 
  {352, 1.7, 0.205882, 102}, {352, 1.8, 0.0392157, 102}, 
  {352, 1.9, 0.00980392, 102}, {352, 2.4, 0.00980392, 102}, 
  {352, 2.7, 0.00980392, 102}, {352, 3.3, 0.00980392, 102}, 
  {352, 4.5, 0.00980392, 102}, {352, 5.6, 0.00980392, 102}, 
  {378, 1.2, 0.00520833, 1728}, {378, 1.3, 0.0300926, 1728}, 
  {378, 1.4, 0.152199, 1728}, {378, 1.5, 0.372106, 1728}, 
  {378, 1.6, 0.307292, 1728}, {378, 1.7, 0.101852, 1728}, 
  {378, 1.8, 0.0202546, 1728}, {378, 1.9, 0.00173611, 1728}, 
  {378, 2, 0.000578704, 1728}, {378, 2.3, 0.000578704, 1728}, 
  {378, 2.5, 0.00173611, 1728}, {378, 2.7, 0.000578704, 1728}, 
  {378, 2.9, 0.000578704, 1728}, {378, 3.1, 0.000578704, 1728}, 
  {378, 3.3, 0.00115741, 1728}, {378, 3.5, 0.00115741, 1728}, 
  {378, 3.8, 0.00115741, 1728}, {378, 4, 0.000578704, 1728}, 
  {378, 4.4, 0.000578704, 1728}, {405, 1.3, 0.00552923, 1266}, 
  {405, 1.4, 0.0947867, 1266}, {405, 1.5, 0.332543, 1266}, 
  {405, 1.6, 0.326224, 1266}, {405, 1.7, 0.172196, 1266}, 
  {405, 1.8, 0.0473934, 1266}, {405, 1.9, 0.00631912, 1266}, 
  {405, 2, 0.00236967, 1266}, {405, 2.4, 0.000789889, 1266}, 
  {405, 2.9, 0.00157978, 1266}, {405, 3, 0.000789889, 1266}, 
  {405, 3.2, 0.00157978, 1266}, {405, 3.5, 0.000789889, 1266}, 
  {405, 3.6, 0.000789889, 1266}, {405, 3.7, 0.00157978, 1266}, 
  {405, 3.8, 0.000789889, 1266}, {405, 3.9, 0.000789889, 1266}, 
  {405, 4, 0.000789889, 1266}, {405, 5, 0.000789889, 1266}, 
  {405, 5.1, 0.000789889, 1266}, {405, 5.4, 0.000789889, 1266}, 
  {439, 1.1, 0.0031746, 630}, {439, 1.2, 0.0650794, 630}, 
  {439, 1.3, 0.185714, 630}, {439, 1.4, 0.271429, 630}, 
  {439, 1.5, 0.277778, 630}, {439, 1.6, 0.103175, 630}, 
  {439, 1.7, 0.047619, 630}, {439, 1.8, 0.00793651, 630}, 
  {439, 2.3, 0.0015873, 630}, {439, 2.5, 0.0015873, 630}, 
  {439, 2.7, 0.0047619, 630}, {439, 2.9, 0.0015873, 630}, 
  {439, 3, 0.0015873, 630}, {439, 3.2, 0.0015873, 630}, 
  {439, 3.3, 0.0031746, 630}, {439, 3.4, 0.0031746, 630}, 
  {439, 3.7, 0.0031746, 630}, {439, 3.8, 0.0031746, 630}, 
  {439, 3.9, 0.0047619, 630}, {439, 4, 0.0031746, 630}, 
  {439, 4.2, 0.0015873, 630}, {439, 4.6, 0.0015873, 630}, 
  {439, 5, 0.0015873, 630}, {467, 1, 0.0121951, 82}, 
  {467, 1.1, 0.0853659, 82}, {467, 1.2, 0.182927, 82}, 
  {467, 1.3, 0.292683, 82}, {467, 1.4, 0.256098, 82}, 
  {467, 1.5, 0.146341, 82}, {467, 1.6, 0.0243902, 82}, 
  {498, 2, 0.0181818, 55}, {498, 2.6, 0.0181818, 55}, 
  {498, 2.7, 0.0909091, 55}, {498, 2.8, 0.0545455, 55}, 
  {498, 2.9, 0.0363636, 55}, {498, 3, 0.0909091, 55}, 
  {498, 3.1, 0.0363636, 55}, {498, 3.2, 0.0363636, 55}, 
  {498, 3.3, 0.2, 55}, {498, 3.4, 0.127273, 55}, 
  {498, 3.5, 0.0909091, 55}, {498, 3.6, 0.0363636, 55}, 
  {498, 3.7, 0.0727273, 55}, {498, 3.8, 0.0363636, 55}, 
  {498, 4.1, 0.0181818, 55}, {498, 4.2, 0.0181818, 55}, 
  {498, 4.3, 0.0181818, 55}, {528, 1.3, 0.0571429, 140}, 
  {528, 1.4, 0.157143, 140}, {528, 1.5, 0.1, 140}, 
  {528, 1.6, 0.0357143, 140}, {528, 2.6, 0.00714286, 140}, 
  {528, 3, 0.00714286, 140}, {528, 3.4, 0.0142857, 140}, 
  {528, 3.5, 0.05, 140}, {528, 3.6, 0.0214286, 140}, 
  {528, 3.7, 0.0357143, 140}, {528, 3.8, 0.0214286, 140}, 
  {528, 3.9, 0.135714, 140}, {528, 4, 0.00714286, 140}, 
  {528, 4.2, 0.114286, 140}, {528, 4.3, 0.0214286, 140}, 
  {528, 4.4, 0.00714286, 140}, {528, 4.5, 0.00714286, 140}, 
  {528, 4.6, 0.107143, 140}, {528, 4.8, 0.0714286, 140}, 
  {528, 5, 0.0214286, 140}, {558, 1.1, 0.00175131, 1142}, 
  {558, 1.2, 0.0262697, 1142}, {558, 1.3, 0.190018, 1142}, 
  {558, 1.4, 0.248687, 1142}, {558, 1.5, 0.230298, 1142}, 
  {558, 1.6, 0.190018, 1142}, {558, 1.7, 0.0936953, 1142}, 
  {558, 1.8, 0.00350263, 1142}, {558, 3.3, 0.000875657, 1142}, 
  {558, 3.8, 0.00350263, 1142}, {558, 4.2, 0.00788091, 1142}, 
  {558, 4.3, 0.000875657, 1142}, {558, 4.4, 0.000875657, 1142}, 
  {558, 4.7, 0.000875657, 1142}, {558, 4.8, 0.000875657, 1142}, 
  {583, 1.2, 0.0716305, 1061}, {583, 1.3, 0.209237, 1061}, 
  {583, 1.4, 0.236569, 1061}, {583, 1.5, 0.233742, 1061}, 
  {583, 1.6, 0.183789, 1061}, {583, 1.7, 0.061263, 1061}, 
  {583, 1.8, 0.00188501, 1061}, {583, 4.3, 0.000942507, 1061}, 
  {583, 4.5, 0.000942507, 1061}, {620, 1.2, 0.00569801, 351}, 
  {620, 1.3, 0.196581, 351}, {620, 1.4, 0.222222, 351}, 
  {620, 1.5, 0.279202, 351}, {620, 1.6, 0.225071, 351}, 
  {620, 1.7, 0.0683761, 351}, {620, 1.8, 0.002849, 351}, 
  {648, 1.1, 0.00854701, 234}, {648, 1.2, 0.0726496, 234}, 
  {648, 1.3, 0.260684, 234}, {648, 1.4, 0.273504, 234}, 
  {648, 1.5, 0.273504, 234}, {648, 1.6, 0.111111, 234}, 
  {676, 1.1, 0.0119048, 84}, {676, 1.2, 0.0595238, 84}, 
  {676, 1.3, 0.297619, 84}, {676, 1.4, 0.22619, 84}, 
  {676, 1.5, 0.285714, 84}, {676, 1.6, 0.107143, 84}, 
  {676, 1.8, 0.0119048, 84}, {704, 0.9, 0.037037, 27}, 
  {704, 1, 0.037037, 27}, {704, 1.2, 0.111111, 27}, 
  {704, 1.3, 0.222222, 27}, {704, 1.4, 0.148148, 27}, 
  {704, 1.5, 0.333333, 27}, {704, 1.7, 0.111111, 27}};

The first entry in each quadruple is the day on which the sample was taken, in terms of number of days from Jan. 1, 1984. The second entry refers to the length of the clam (really an interval; 1.4 means length between 1.35 and 1.45 millimeters), the third is the fraction of the sample that occurred having that length, the fourth is the total number of clam in the sample. So, {256, 1.8, 0.136, 125} means that on Sept. 13, 1984, 13.6% of the 125 clams examined that day had length between 1.75 and 1.85 millimeters.

The code for generating the chart is straightforward. We first define dataRect to make the rectangle corresponding to a given data vector; it took some experimentation to get the horizontal spacing right (the constant 40). The five rectangles making up the legend were obtained by adding some auxiliary entries to the data set. Then dataRect is mapped onto the data set, and the result is shown.

nMax = Max[Last[Transpose[data]]];

dataRect[{day_, length_, frac_, n_}] := Module[{w = 40 frac},
 {{GrayLevel[1 - n/nMax],
    Rectangle[{day - w, length - 0.05},
	          {day + w, length + 0.05}]}, 
  {AbsoluteThickness[0.3], Line[{{day - w, length - 0.05}, 
       {day - w, length + 0.05}, {day + w, length + 0.05}, 
       {day + w, length - 0.05}, {day - w, length - 0.05}}]} }]

dataWithLegend = Join[data, { {650, 7.3, 0.25, nMax},
   {650, 6.9, 0.25, 0.5  nMax}, {650, 6.5, 0.25, 0.1 nMax},
   {650, 6.1, 0.25, 0.05 nMax}, {650, 5.7, 0.25, 0.025 nMax}}];
  (* this appends coordinates for the five legend rectangles *)

Show[Graphics[{Map[dataRect, dataWithLegend],
  Text[  "43", {687, 5.7}, {1,0}], Text[  "86", {687, 6.1}, {1,0}],
  Text[ "173", {687, 6.5}, {1,0}], Text[ "864", {687, 6.9}, {1,0}],
  Text["1728", {687, 7.3}, {1,0}]}],
 PlotRange->{{235, 731}, {0, 8}}, AspectRatio->24/40, 
 Frame->True, DefaultFont->{"Helvetica", 6}, FrameTicks->
   { {{244, "Sept"}, {274, "Oct"}, {305, "Nov"}, 
      {335, "Dec"}, {366, "Jan"}, {397, "Feb"}, {425, "Mar"}, 
      {456, "Apr"}, {486, "May"}, {517, "June"},{547, "July"}, 
      {578, "Aug"}, {609, "Sept"}, {639, "Oct"}, {670, "Nov"},
      {710, "Dec 1985"}}, {#, StringForm["`` mm", #]} & /@ Range[7]}];

It is true that graphics output can be exported to a drawing program and labels and the like added there somewhat more conveniently than within Mathematica. But there are many advantages to staying within a single program; in particular, the final chart can be communicated easily by e-mail: just send the Mathematica code that generated it.

References

1.  D. J. Hornbach, T. Deneka, and R. Dado, Life cycle variation of Musculium patrumeium (Bivalvia:Sphaeriidae) from a temporary and permanent pond in Minnesota, Canadian Journal of Zoology 69 (1991) 2738—2744.

2. H. J. Jeffrey, Chaos game representation of gene structure, Nucleic Acids Research 18 (1990), 2163—2170.

3. H. J. Jeffrey, Chaos game visualization of sequences, Computers & Graphics 16 (1992) 25—33.

4.  D. Peak and M. Frame, Chaos Under Control, W. H. Freeman, New York, 1994.