Histograms in grap
Saturday, July 28th, 2018I know everyone loves it when I talk about arcane typesetting languages, so here’s a response to a fellow who wanted to replicate the histograms at http://www.jmillville.com/project/learnstats/ex9.html in grap.
Attached is a commented grap/groff file that draws something like both histograms. I commented the grap to explain what I was up to (comments start with .\"), but feel free to ask about anything that's confusing. I didn't see immediately how he set the widths of his histogram bars/buckets, so I used 10-pound-wide buckets centered on 105,110,115... for all crew (blue) and 5-pound-wide buckets centered on 105,110,115,120... for the rowers (green). (The bucket width is both the clustering range and the width of the histogram bars.) I've attached the grap/groff (called hist.ms), the data file I used called data, and the postscript it generates when I call $ groff -Gp hist > hist.ps on my ubuntu box with groff and grap installed. I used grap 1.45 from a stock ubuntu .deb. If I wanted to do this same task as flexibly as possible, I'd probably preprocess the data using a scripting language and then generate grap output that I'd run through groff as above. I'm slowly writing a pic to svg program in my spare time that would make that more portable to use. Hope that helps some.
The grap script looks like this:
.G1 .\" Initialize globals tot105 = tot115 = tot125 = tot135 = tot145 = tot155 = 0 tot165 = tot175 = tot185 = tot195 = tot205 = tot215 = 0 rtot105 = rtot115 = rtot125 = rtot135 = rtot145 = rtot155 = 0 rtot165 = rtot175 = rtot185 = rtot195 = rtot205 = rtot215 = 0 rtot110 = rtot120 = rtot130 = rtot140 = rtot150 = 0 rtot160 = rtot170 = rtot180 = rtot190 = rtot200 = rtot210 = 0 .\" between takes teh following args in order .\" $1: value to test .\" $2: center of bucket .\" $3: bucket width .\" $4: variable stem .\" if the test value is in the bucket (between the center +/- width/2) .\" the macro increments the variable made from concatenating the stem and .\" the bucket center. define between { if ($1 >= $2-($3/2) && $1 < $2+($3/2) ) then { $4$2 = $4$2 + 1 } } .\" Copy the test data through between calls to set the globals copy "data" thru { between($1,105,10,tot) between($1,115,10,tot) between($1,125,10,tot) between($1,135,10,tot) between($1,145,10,tot) between($1,155,10,tot) between($1,165,10,tot) between($1,175,10,tot) between($1,185,10,tot) between($1,195,10,tot) between($1,205,10,tot) between($1,215,10,tot) if ($3 == 1) then { between($1,105,5,rtot) between($1,110,5,rtot) between($1,115,5,rtot) between($1,120,5,rtot) between($1,125,5,rtot) between($1,130,5,rtot) between($1,135,5,rtot) between($1,140,5,rtot) between($1,145,5,rtot) between($1,150,5,rtot) between($1,155,5,rtot) between($1,160,5,rtot) between($1,165,5,rtot) between($1,170,5,rtot) between($1,175,5,rtot) between($1,180,5,rtot) between($1,190,5,rtot) between($1,185,5,rtot) between($1,195,5,rtot) between($1,200,5,rtot) between($1,205,5,rtot) between($1,210,5,rtot) between($1,215,5,rtot) } } .\" Set up the coordinates and the ticks to match the example coord x 100, 220 y 0,8 ticks bot in 0.02 down 0.04 from 100 to 220 by 20 ticks top in 0.02 from 100 to 220 by 20 "" ticks left in 0.02 left 0.08 from 0 to 8 ticks right in 0.02 from 0 to 8 "" label left "Number of Members" label bot "Weight in Pounds" label top "The Boat Race Crew Histograms" size +2 .\" Draw bars for both kinds of crew
bar up 105 ht tot105 wid 10 fillcolor "blue" bar up 115 ht tot115 wid 10 fillcolor "blue" bar up 125 ht tot125 wid 10 fillcolor "blue" bar up 135 ht tot135 wid 10 fillcolor "blue" bar up 145 ht tot145 wid 10 fillcolor "blue" bar up 155 ht tot155 wid 10 fillcolor "blue" bar up 165 ht tot165 wid 10 fillcolor "blue" bar up 175 ht tot175 wid 10 fillcolor "blue" bar up 185 ht tot185 wid 10 fillcolor "blue" bar up 195 ht tot195 wid 10 fillcolor "blue" bar up 205 ht tot205 wid 10 fillcolor "blue" bar up 215 ht tot215 wid 10 fillcolor "blue" .\" Draw bars for rowers bar up 105 ht rtot105 wid 5 fillcolor "forestgreen" bar up 110 ht rtot110 wid 5 fillcolor "forestgreen" bar up 115 ht rtot115 wid 5 fillcolor "forestgreen" bar up 120 ht rtot120 wid 5 fillcolor "forestgreen" bar up 125 ht rtot125 wid 5 fillcolor "forestgreen" bar up 130 ht rtot130 wid 5 fillcolor "forestgreen" bar up 135 ht rtot135 wid 5 fillcolor "forestgreen" bar up 140 ht rtot140 wid 5 fillcolor "forestgreen" bar up 145 ht rtot145 wid 5 fillcolor "forestgreen" bar up 150 ht rtot150 wid 5 fillcolor "forestgreen" bar up 155 ht rtot155 wid 5 fillcolor "forestgreen" bar up 160 ht rtot160 wid 5 fillcolor "forestgreen" bar up 165 ht rtot165 wid 5 fillcolor "forestgreen" bar up 170 ht rtot170 wid 5 fillcolor "forestgreen" bar up 175 ht rtot175 wid 5 fillcolor "forestgreen" bar up 180 ht rtot180 wid 5 fillcolor "forestgreen" bar up 185 ht rtot185 wid 5 fillcolor "forestgreen" bar up 190 ht rtot190 wid 5 fillcolor "forestgreen" bar up 195 ht rtot195 wid 5 fillcolor "forestgreen" bar up 200 ht rtot200 wid 5 fillcolor "forestgreen" bar up 205 ht rtot205 wid 5 fillcolor "forestgreen" bar up 210 ht rtot210 wid 5 fillcolor "forestgreen" bar up 215 ht rtot215 wid 5 fillcolor "forestgreen" .\" Draw a key (Note that the positions here are in the histogram coordinates) bar 102, 7.8, 155, 6.5 bar 105, 7.6, 120, 7.2 fillcolor "blue" bar 105, 7.0, 120, 6.6 fillcolor "forestgreen" "rowers and coxswains" ljust size -4 at 122, 7.4 "rowers and coxswains" ljust size -4 at 122, 6.8 .G2
Enjoy!