-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbargraph.html
More file actions
executable file
·1043 lines (882 loc) · 37.1 KB
/
Copy pathbargraph.html
File metadata and controls
executable file
·1043 lines (882 loc) · 37.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html public "-//IETF//DTD HTML//EN">
<html>
<head>
<script type="text/javascript">
<!-- Begin
function mailnospam(user, site, display) {
document.write('<a href=\"mailto:' + user + '@' + site + '\">');
document.write(display + '</a>');
}
// End -->
</script>
<title>Clustered/Stacked Filled Bar Graph Generator</title>
</head>
<body bgcolor="ffffff" text="000000" link="000088" vlink="006600">
<table width="100%" cellspacing=0 cellpadding=5 border=0>
<tr><td align="right"><img src="cluster_sm.png"></td>
<td width=100> </td>
<td align="left"><img src="stacked_100_sm.png"></td>
</tr></table>
<center>
<h1>Clustered/Stacked Filled Bar Graph Generator</h1>
</center>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong>The Script</strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<p>
<img align="right" src="stacked_var_sm.png">
I wanted a scriptable bar graph generator for my <a href="/derek/phd.html">PhD
thesis</a> that supported stacked and clustered bars, but couldn't find one
that played well with latex and had all the features I wanted, so I built
my own. I followed the scheme of <a
href="http://www.togaware.com/datamining/gdatamine/barchart">Graham
Williams' barchart shell script</a> to have gnuplot produce fig output and
then mangle it to fill in the bars. I added support for more than just two
or three clustered datasets and support for stacked bars, as well as
automatic averaging and other features.
</p>
<p>The script
is <a href="http://bargraphgen.googlecode.com/svn/trunk/bargraph.pl">bargraph.pl</a>,
released under the <a href="gpl.txt">GPL</a>. A package that includes the
script and samples is
also <a href="http://code.google.com/p/bargraphgen/downloads/list">
available</a>.
</p>
<p>Features:
<ul>
<li>Stacked bars of 9+ datasets
<li>Clustered bars of 8+ datasets
<li>Clusters of stacked bars
<li>Lets you keep your data in table format, or separated but listed in the
same file, rather than requiring each dataset to be in a separate file
<li>Custom gnuplot command pass-through for fine-grained customization
without having a separate tool chain step outside the script
<li>Bars can be pattern filled or use solid colors
<li>Font face control and limited font size control
<li>Automatic arithmetic or harmonic mean calculation
<li>Automatic legend creation
<li>Automatic legend placement in empty space inside the graph
<li>Automatic sorting, including sorting into SPEC CPU 2000 integer and
floating point benchmark groups and sorting by data
<li>Error bar support
</ul>
</p>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong>Usage</strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<p>
The script's usage message shows the command-line options:
<pre>
Usage: bargraph.pl [-gnuplot] [-fig] [-pdf] [-png [-non-transparent]] [-eps] <graphfile>
File format:
<graph parameters>
<data>
Graph parameter types:
<value_param>=<value>
=<bool_param>
</pre>
The script takes in a single file that specifies the data to graph and
control parameters for customizing the graph. The parameters must precede
the data in the file. Comments can be included in a graph file following the
<tt>#</tt> character.</p>
<p>
The script's output, by default, is encapsulated postscript (.eps), which
is sent to stdout. Simply redirect it to the desired output file:
<pre>
bargraph.pl mygraphfile > mygraphfile.eps
</pre>
</p>
<p>
The script first produces data to send to gnuplot, which can be
seen by specifying
<tt>-gnuplot</tt>. Next, the script takes the resulting fig output from
gnuplot and post-processes it to fill in the bars. The final fig data can
also be selected via <tt>-fig</tt>. This data is then sent to fig2dev to
produce a final figure.
</p>
<p>I keep my data in .perf files and have my Makefile generate .eps for
latex and .png for slides or web pages. See <a href="#Bitmap">converting
to non-vector formats</a> for notes on avoiding aliasing and other problems
when creating images, and for some Makefile rules. My script magnifies 2x
when converting to png to help avoid these problems, but for most uses
that's not enough and you should follow <a href="#Bitmap">my
suggestions</a> rather than using -png. My default for -png produces a
transparent background; the -non-transparent option disables that feature.
</p>
<p>The following sections describe each graph parameter.</p>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong>Multiple Datasets</strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<ul>
<li><p><a name="cluster"><strong>=cluster</strong></a><br>
Indicates that there are multiple datasets that should be displayed as
clustered bars. This command also provides the names of the datasets.
The character following =cluster is taken as a delimiter separating
the rest of the line into strings naming each dataset. Some examples:
<pre>
=cluster;Irish elk;Dodo birds;Coelecanth
=cluster Monday Tuesday Wednesday Thursday Friday
=cluster+Fast; slow+Slow; fast
</pre>
The data itself must either be in <a href="#table">table format</a> or
each dataset must be separated by <a href="#multi">=multi</a>.
</p></li>
<li><p><a name="stacked"><strong>=stacked</strong></a><br>
Just like <a href="#cluster">=cluster</a>, this indicates that there
are multiple datasets, but to be displayed as stacked bars rather than
clustered bars. The data must be either in <a href="#table">table
format</a> or delimited by <a href="#multi">=multi</a>. The names of
the datasets are delimited as with <a href="#cluster">=cluster</a>:
<pre>
=stacked,Irish elk,Dodo birds,Coelecanth
</pre>
</p></li>
<li><p><a name="stacked"><strong>=stackabs</strong></a><br>
Stacked data is normally given in relative values that are added
to produce the absolute values of each bar. This option indicates
that each datum is an absolute value. As an example, consider this data:
<pre>
foo 10 20 30
</pre>
By default this would be stacked at 10, 30, and 60, with the given
values indicating the difference between each stacked bar's height.
With =stackabs the bars would have heights of 10, 20, and 30.
</p></li>
<li><p><a name="table"><strong>=table</strong></a><br>
Indicates that the data will be listed in columns. This is much more
compact and readable than listing each column separately, though that
can be done using the <a href="#multi">=multi</a> separation marker.
If there is a character after =table it is taken to be the column
delimiter in the table; otherwise, the table is split by spaces, with
multiple adjacent spaces being collapsed into one. Extra leading and
trailing spaces around each datum are removed.
The table should look something like this:
<pre>
<benchmark1> <dataset1> <dataset2> <dataset3> ...
<benchmark2> <dataset1> <dataset2> <dataset3> ...
...
</pre>
An example:
<pre>
=table
age 37 9 22
height 17 12 20
weight 92 52 84
</pre>
An example with a custom delimiter:
<pre>
=table,
age, 37, 9, 22
height, 17, 12, 20
weight, 92, 52, 84
</pre>
</p></li>
<li><p><a name="multi"><strong>=multi</strong></a><br>
When data is not in <a href="#table">table format</a>, multiple
datasets must be separated by this marker. For example:
<pre>
age 37
height 17
weight 92
=multi
age 9
height 12
weight 52
=multi
age 22
height 20
weight 84
</pre>
</p></li>
<li><p><strong>column=</strong><br>
Some of my data is produced by other scripts that place other fields on
each line. For example, one script shows me the ratio of time,
working set size, and virtual memory size between two benchmark runs.
Rather than requiring another script to strip out the proper column of
numbers, you can simply specify which column contains the numbers to
graph with this parameter. The column numbers begin at 1, which is
assumed to always be the benchmark name. The special token
<tt>last</tt> can be used to indicate the final column. The columns
must be delimited by spaces. Examples:
<pre>
column=last
column=4
</pre>
</p></li>
<li><p><a name="stackcluster"><strong>=stackcluster</strong></a><br>
Just like <a href="#cluster">=cluster</a>, this indicates that there
are multiple datasets, but here we have an extra dimension and the
data is displayed as clusters of stacked bars. Each cluster is itself
like a <a href="#stacked">=stacked</a> dataset, and must be either in
<a href="#table">table format</a> or delimited by <a
href="#multi">=multi</a>. The names of the stacked datasets are
delimited as with <a href="#cluster">=cluster</a> and are used in the
legend:
<pre>
=stackcluster;Basic Blocks;Traces;Hashtables;Stubs
</pre>
The clusters are then separated (and optionally named) by <a
href="#multimulti">multimulti=</a>. If any name is given in any <a
href="#multimulti">multimulti=</a> parameter, then cluster labels are
used. If there is no <a href="#xlabel">xlabel=</a>, then the cluster
labels are placed below the x axis tic mark labels. If there are no x
tic marks (<a href="#noxlabels">=noxlabels</a>) then the cluster
labels are centered under each cluster in place of tic mark labels.
There is no support for putting the cluster labels in the legend.
</p><p>
My script does not support automatically calculating the mean (<a
href="#arithmean">=arithmean</a> or <a href="#harmean">=harmean</a>)
for clusters of stacked bars.
</p></li>
<li><p><a name="multimulti"><strong>multimulti=</strong></a><br>
Separates the <a href="#table">table</a> or <a
href="#multi">=multi</a> delimited data of a <a
href="#stackcluster">=stackclustertable</a> graph, and optionally
names each cluster with the string after the <tt>multimulti=</tt>
token. An example:
<pre>
=stackcluster;Basic Blocks;Traces;Hashtables;Stubs
=table
multimulti=Private Caches
ammp 25.635 23.094 14.780 5.543
applu 25.035 27.375 14.974 4.913
multimulti=Shared Caches
ammp 27.863 18.913 15.536 5.404
applu 24.501 18.657 11.689 4.720
multimulti=Persistent Caches
ammp 17.863 11.913 19.536 9.404
applu 34.501 12.657 18.689 7.720
</pre>
</p></li>
<li><p><strong>=yerrorbars</strong><br>
Specifies that vertical error bars are to be displayed for each datum.
This option is not supported with <a href="#stacked">=stacked</a>
or <a href="#stackcluster">=stackcluster</a> graphs. The error bar
data follows this directive, in the same format (including optional
non-space delimiter) as <a href="#table">=table</a> (non-table-format
error bar data is not supported).
</p></li>
<li><p><strong>colors=</strong><br>
The script was tuned with sets of colors designed to have maximum
contrast when printed on a non-color printer, yet still look good on a
color display. Non-default color orderings can be chosen using this
parameter. The available color names are:
</p><p>
<table cellspacing=0 cellpadding=5 border=0>
<tr><td width=30 rowspan=12> </td>
<td colspan=2><em>color graphs</em></td>
<td width=30> </td>
<td colspan=2><em>grayscale graphs</em></td></tr>
<tr><td>black</td><td width=50 bgcolor="#000000"> </td><td> </td>
<td>black</td><td width=50 bgcolor="#000000"> </td>
</tr>
<tr><td>grey</td><td bgcolor="#dddddd"> </td><td> </td>
<td>grey1</td><td bgcolor="#222222"> </td>
</tr>
<tr><td>yellow</td><td bgcolor="#ffff00"> </td><td> </td>
<td>grey2</td><td bgcolor="#444444"> </td>
</tr>
<tr><td>dark_blue</td><td bgcolor="#0000ff"> </td><td> </td>
<td>grey3</td><td bgcolor="#666666"> </td>
</tr>
<tr><td>med_blue</td><td bgcolor="#6666ff"> </td><td> </td>
<td>grey4</td><td bgcolor="#888888"> </td>
</tr>
<tr><td>light_blue</td><td bgcolor="#aaaaff"> </td><td> </td>
<td>grey5</td><td bgcolor="#aaaaaa"> </td>
</tr>
<tr><td>cyan</td><td bgcolor="#00ffff"> </td><td> </td>
<td>grey6</td><td bgcolor="#cccccc"> </td>
</tr>
<tr><td>light_green</td><td bgcolor="#77ff00"> </td><td> </td>
<td>grey7</td><td bgcolor="#eeeeee"> </td>
</tr>
<tr><td>dark_green</td><td bgcolor="#00aa00"> </td><td> </td>
<td></td><td></td>
</tr>
<tr><td>magenta</td><td bgcolor="#dd00ff"> </td><td> </td>
<td></td><td></td>
</tr>
<tr><td>red</td><td bgcolor="#ff0000"> </td><td> </td>
<td></td><td></td>
</tr>
</table>
</p><p>
Colors should be separated by commas and listed in order, specifying
the color for each dataset. An example:
<pre>
colors=black,yellow,red,med_blue,dark_green
</pre>
</p></li>
<li><p><strong>=patterns</strong><br>
Specifies that pattern fills rather than solid colors should be used
to fill the bars. There are 22 fig patterns, which are re-used for
dataset counts higher than 22.
</p></li>
<li><p><strong>=color_per_datum</strong><br>
Specifies that a different color should be used for each datum. Does
not work with patterns. With clusters, the legend is not very useful.
</p></li>
</ul>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong>Data Manipulation</strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<ul>
<li><p><strong>logscaley=</strong><br>
Use a logarithmic scale for the y axis, with the specified base. For example:
<pre>
logscaley=10
</pre>
</p></li>
<li><p><strong>=invert</strong><br>
Each datum is inverted before graphing (<tt>datum</tt> becomes <tt>1/datum</tt>).
</p></li>
<li><p><strong>=percent</strong><br>
Each datum is transformed to <tt>(datum - 1) * 100</tt> before graphing.
This happens after scaling by base1, datasub, or datascale.
</p></li>
<li><p><strong>=base1</strong><br>
Each datum is transformed to <tt>(datum - 1)</tt> before graphing.
</p></li>
<li><p><strong>datasub=</strong><br>
The specified number is subtracted from each datum prior to graphing.
</p></li>
<li><p><strong>datascale=</strong><br>
Each datum is multiplied by the specified number prior to graphing.
</p></li>
<li><p><strong>=reverseorder</strong><br>
The benchmarks are placed in the reverse order to their order in the
source file.
</p></li>
<li><p><strong>=sort</strong><br>
The benchmarks are sorted alphabetically by name.
</p></li>
<li><p><strong>=sortbmarks</strong><br>
The benchmarks are sorted into SPEC benchmark categories: first SPEC
CPU 2000 FP, then SPEC CPU 2000 INT, then SPEC JVM 98. Any benchmarks
not in these categories are placed at the end. This was very useful
for my thesis.
</p></li>
<li><p><strong>=sortdata_ascend</strong><br>
The benchmarks are sorted by data value, in ascending order.
For multiple datasets the first dataset is the only one considered.
Any automatic average is placed at the end.
</p></li>
<li><p><strong>=sortdata_descend</strong><br>
The benchmarks are sorted by data value, in descending order.
For multiple datasets the first dataset is the only one considered.
Any automatic average is placed at the end.
</p></li>
<li><p><a name="arithmean"><strong>=arithmean</strong></a><br>
The arithmetic mean is calculated and displayed under the label "mean"
unless specified otherwise by the <a href="#meanlabel">meanlabel</a>
parameter. The mean is always placed at the end of the benchmarks.
The mean is not supported for <a href="#stackcluster">=stackcluster</a>
graphs.
</p></li>
<li><p><a name="harmean"><strong>=harmean</strong></a><br>
The harmonic mean is calculated and displayed under the label "har_mean"
unless specified otherwise by the <a href="#meanlabel">meanlabel</a>
parameter. The mean is always placed at the end of the benchmarks.
The mean is not supported for <a href="#stackcluster">=stackcluster</a>
graphs.
</p></li>
<li><p><a name="meanlabel"><strong>meanlabel=</strong></a><br>
Specifies a different label for the <a href="#arithmean">arithmetic</a>
or <a href="#harmean">harmonic</a> mean.
</p></li>
<li><p><strong>min=</strong><br>
Sets the minimum y value displayed. Any values below this are simply
cut off at this value.
</p></li>
<li><p><strong>max=</strong><br>
Sets the maximum y value displayed. Any values above this are simply
cut off at this value.
</p></li>
<li><p><strong>=nocommas</strong><br>
Disables the insertion of commas in large numbers, which the script
adds by default.
</p></li>
</ul>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong>Graph Display</strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<ul>
<li><p><strong>title=</strong><br>
Sets the title of the graph.
</p></li>
<li><p><a name="xlabel"><strong>xlabel=</strong></a><br>
Sets the label for the x axis.
</p></li>
<li><p><a name="xlabelshift"><strong>xlabelshift=</strong></a><br>
This is passed straight to gnuplot. The default is "0,-1". An example
is moving the x axis label closer to the x axis:
<pre>
xlabelshift=0,1
</pre>
</p></li>
<li><p><strong>ylabel=</strong><br>
Sets the label for the y axis.
</p></li>
<li><p><strong>ylabelshift=</strong><br>
This is passed straight to gnuplot. The default is "0,0". An example
is moving the y axis label closer to the y axis:
<pre>
ylabelshift=2,0
</pre>
</p></li>
<li><p><strong>yformat=</strong><br>
Specifies the format for the y tic mark labels. This is passed
straight to gnuplot, which requires a printf-style format specifier
that can accept a double-precision value. Examples:
<pre>
yformat=%g
yformat=%4.2f%%
</pre>
</p></li>
<li><p><strong>=norotate</strong><br>
By default, x tic mark labels (not the x axis label) are placed
vertically. This indicates that they should not be rotated and should
remain horizontal.
</p></li>
<li><p><strong>rotateby=</strong><br>
By default, x tic mark labels are placed vertically, which means
rotating them 90 degrees. The rotation can be controlled through this
parameter, in units of degrees. Negative degress are recommended. For
positive degrees, the
<a href="#xticshift">xticshift</a> parameter may be needed to shift the
rotated tic mark labels to lie entirely under the x-axis, and they
may end up not being included in the graph. Future versions of the
script will try to address this gnuplot behavior.
</p></li>
<li><p><strong>grouprotateby=</strong><br>
By default, group labels for clusters-of-stacked-bars graphs
(see <a href="#stackcluster">=stackcluster</a> are horizontal.
This option rotates the labels, in units of degrees.
Negative degress are recommended.
</p></li>
<li><p><a name="xticshift"><strong>xticshift=</strong></a><br>
This is passed straight to gnuplot. The default is "0,0". An example
is moving the x tic mark labels closer to the x axis:
<pre>
xticshift=0,1
</pre>
Note that gnuplot seems willing to move these labels beyond the bounding
box of the resulting graph so be careful moving them away from the axis.
</p></li>
<li><p><a name="noxlabels"><strong>=noxlabels</strong></a><br>
This specifies that x tic mark labels should not be displayed.
</p></li>
<li><p><strong>=noupperright</strong><br>
Specifies that the top and right side lines delimiting the graph area
should be omitted.
</p></li>
<li><p><strong>=gridx</strong><br>
Requests that x grid lines be displayed.
</p></li>
<li><p><strong>=nogridy</strong><br>
Requests that y grid lines not be displayed (they are by default).
</p></li>
<li><p><strong>leading_space_mul=</strong><br>
Controls the amount of leading and trailing horizontal space
on the outer edges of the data in the graph. The default is 1.0
plus a per-clustered-bar amount.
This value is multiplied by the bar width (see
<a href="#barwidth">barwidth=</a>).
</p></li>
<li><p><strong>intra_space_mul=</strong><br>
Controls the amount of space between bars or clusters of bars for a
clustered graph. The default is 1.0 plus a small per-clustered-bar
amount. This value is multiplied by the bar width
(see <a href="#barwidth">barwidth=</a>).
</p></li>
<li><p><a name="barwidth"><strong>barwidth=</strong></a><br>
Specifies the width of each bar. Since the whole graph is scaled
relative to the bar width, usually this parameter does not need to be
changed.
</p></li>
<li><p><strong>=nolegend</strong><br>
Disables display of the legend.
</p></li>
<li><p><a name="legendx"><strong>legendx=</strong></a><br>
Sets the x location of the legend. The keywords "inside", "right", or
"center" may be used, or a numeric coordinate. The default is
"inside", which requests that the legend be placed inside the graph but
above the bars. When "inside" is specified,
the <a href="#legendy">legendy=</a> parameter is ignored. If not
enough space can be found inside the graph, the equivalent of
legendx=center legendy=top is used as a fallback, placing the legend
above the graph and centered horizontally. Note that using numeric
values may take trial and error to get the coordinates right.
</p></li>
<li><p><a name="legendy"><strong>legendy=</strong></a><br>
Sets the y location of the legend. The keywords "top" or "center" may
be used, or a numeric coordinate. See <a href="#legendy">legendx=</a>
for the defaults and further information.
</p></li>
<li><p><strong>legendfill=</strong><br>
By default the legend has a white filled background. With no argument,
this option removes the fill altogether. With a color name, it sets the
fill color.
</p></li>
<li><p><strong>=nolegoutline</strong><br>
By default the legend has a black border. This option removes that
border.
</p></li>
<li><p><strong>=legendinbg</strong><br>
By default the legend is in the foreground. This option places the
legend in the background, behind the plot.
</p></li>
<li><p><strong>horizline=</strong><br>
Draws a horizontal line at the specified y value. May be repeated.
</p></li>
<li><p><a name="font"><strong>font=</strong></a><br>
Specifies a global font substitution. The script supports the full
set of Postscript fonts that the FIG format supports, which are:
<ul>
<li>Times</li>
<li>Times Italic</li>
<li>Times Bold</li>
<li>Times Bold Italic</li>
<li>AvantGarde Book</li>
<li>AvantGarde Book Oblique</li>
<li>AvantGarde Demi</li>
<li>AvantGarde Demi Oblique</li>
<li>Bookman Light</li>
<li>Bookman Light Italic</li>
<li>Bookman Demi</li>
<li>Bookman Demi Italic</li>
<li>Courier</li>
<li>Courier Oblique</li>
<li>Courier Bold</li>
<li>Courier Bold Oblique</li>
<li>Helvetica</li>
<li>Helvetica Oblique</li>
<li>Helvetica Bold</li>
<li>Helvetica Bold Oblique</li>
<li>Helvetica Narrow</li>
<li>Helvetica Narrow Oblique</li>
<li>Helvetica Narrow Bold</li>
<li>Helvetica Narrow Bold Oblique</li>
<li>New Century Schoolbook Roman</li>
<li>New Century Schoolbook Italic</li>
<li>New Century Schoolbook Bold</li>
<li>New Century Schoolbook Bold Italic</li>
<li>Palatino Roman</li>
<li>Palatino Italic</li>
<li>Palatino Bold</li>
<li>Palatino Bold Italic</li>
<li>Symbol</li>
<li>Zapf Chancery Medium Italic</li>
<li>Zapf Dingbats</li>
</ul>
</p><p>
However, this script is post-processing the gnuplot layout of the text
using the default font of Times size 10, and will not shift text
around, so you may have text running into other plot elements. See
also notes about changing the font size (<a
href="#fontsz">fontsz</a>=).
</p></li>
<li><p><a name="custfont"><strong>custfont=<fontname>=<string></strong></a><br>
Specifies a different font to be used for a particular string within
the graph. Only a whole string will be matched. The intent is to allow
making specific axis labels bold. The font name must
come from the list of fonts given for <a href="#font">font</a>=.
</p></li>
<li><p><a name="fontsz"><strong>fontsz=</strong></a><br>
Specifies a different font size to be globally applied. As for
changing the font face (<a href="#fontsz">font</a>=), remember that
the script is post-processing gnuplot's layout of the text elements of
the graph, which will not be changed. Thus, increasing the size
may cause overlaps among items on the graph. Also note the <a
href="#bbfudge">bounding box calculation hacks</a> that this script
uses.
</p></li>
<li><p><strong>legendfontsz=</strong><br>
By default, the legend font size equals the global font size minus 1.
This option overrides that with an absolute font size for the legend.
See also the general notes about changing font sizes (<a
href="#fontsz">fontsz</a>=).
</p></li>
<li><p><a name="bbfudge"><strong>bbfudge=</strong></a><br>
Changing the <a href="#font">font face</a> or <a
href="#fontsz">size</a> requires a change in the bounding box of each
text element in the graph. The proper way to calculate that is to
call X library routines to get the text extents, but such an interface
is not standard for perl, so my script currently uses hacks to guess
at the bounding box differences. If you find your resulting graph has
text clipped on the edge of the graph, or you have too much whitespace
at the edges, you can try setting this bounding box fudge parameter.
Its default value is 1.0; a larger value increases the bounding
boxes while a smaller-than-1 value decreases the boxes.
</p></li>
<li><p><strong>extraops=</strong><br>
Specifies an option to pass straight through to gnuplot, for
fine-grained control over the graph without having to use a separate
tool chain step. I typically use this to place value labels or to set
the shape of the graph. Examples:
<pre>
# add a text label for a value that goes beyond the max= value
extraops=set label "55" at 2.3,15.6 right font "Times,10"
# stretch the graph vertically
extraops=set size 1,1.4
# stretch the graph horizontally
extraops=set size 1.2,1
</pre>
Note that there is <a href="#gnuplot-bug">a bug in gnuplot 4.2</a> that
is triggered when stretching graphs.
</p></li>
</ul>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong><a name="Examples">Examples</a></strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<ul>
<li>
<p>A simple bar graph with a harmonic mean average.<br>
<a href="simple.perf">[source file]</a></p>
<img src="simple.png">
</li>
<li>
<p>A clustered bar graph with an in-graph legend.<br>
<a href="cluster.perf">[source file]</a></p>
<img src="cluster.png">
</li>
<li>
<p>The same graph but using patterns rather than solid colors.<br>
<a href="cluster-pattern.perf">[source file]</a></p>
<img src="cluster-pattern.png">
</li>
<li>
<p>A simple bar graph using a separate color per datum.<br>
<a href="one_dataset_colors.perf">[source file]</a></p>
<img src="one_dataset_colors.png">
</li>
<li>
<p>A stacked all-100% bar graph<br>
<a href="stacked_100.perf">[source file]</a></p>
<img src="stacked_100.png">
</li>
<li>
<p>A stacked variable-height bar graph.<br>
<a href="stacked_var.perf">[source file]</a></p>
<img src="stacked_var.png">
</li>
<li>
<p>A cluster-of-stacked-bars graph.<br>
<a href="cluster_stacked.perf">[source file]</a></p>
<img src="cluster_stacked.png">
</li>
<li>
<p>A bar graph with error bars.<br>
<a href="errorbar.perf">[source file]</a></p>
<img src="errorbar.png">
</li>
<li>
<p>An example of changing the font.<br>
<a href="font.perf">[source file]</a></p>
<img src="font.png">
</li>
<li>
<p>An example of displaying explicit values.<br>
<a href="value_label.perf">[source file]</a></p>
<img src="value_label.png">
</li>
<li>
<p>An example of missing data in a dataset. <tt>ammp</tt> is misspelled as
<tt>am-mp</tt>, resulting in these warnings:
<pre>
WARNING: missing value for am-mp in dataset 0
WARNING: missing value for ammp in dataset 1
</pre>
<a href="missing_data.perf">[source file]</a></p>
<img src="missing_data.png">
</li>
</ul>
<p> </p>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong><a name="Bitmap">Converting to Non-Vector Formats</a></strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<p>
<img align="right" width=400 src="bad_quality.png">
Because <tt>fig2dev</tt> does not perform anti-aliasing, converting
directly to an image format can result in very poor quality lines and
text. This problem is compounded if that image is subsequently resized
without any anti-aliasing, such as by your web browser: a case in point
is the image on the right.
</p>
<p>
The solution is to magnify the vector data to at least 4x and then generate
a lossless bitmap format, such as TIFF. From there, have a real image
manipulator (such as <tt>mogrify</tt>) resize it to the size you want. For
displaying in html, you should choose the final size at this point -- you
cannot really make browser-resizable bar graphs.
</p>
<p>
Below are my Makefile rules for creating the .png images for this page,
including removing the 2nd TIFF page (I don't know why fig2dev generates
it). Note that mogrify preserves the image's aspect ratio by default, so
asking for 700x700 asks for the image to be shrunk so that its longest
dimension is 700.
<pre>
SIZE=700
%.png: %.tiff
mogrify -resize ${SIZE}x${SIZE} -format png $<
# older mogrify uses these names:
# rm $@.1
# mv $@.0 $@
rm $*-1.png
mv $*-0.png $@
%.tiff: %.perf
bargraph.pl -fig $< | fig2dev -L tiff -m 4 > $@
</pre>
</p>
<p>
The latest gnuplot patterns contains lines that are much closer together
than they used to be. With magnification of 4 or higher they shrink down
into gray uniformity (can't see individual # lines), so for a pattern plot,
a 2-times magnification seems to work the best.
</p>
<p>
For including in slides, <tt>PowerPoint</tt> does perform anti-aliasing,
and I found that going straight to png from fig with a magnification of 4x
was enough to be able to resize the image in <tt>PowerPoint</tt> and have
it look good at any size:
<pre>
%.png: %.perf
bargraph.pl -fig $< | fig2dev -L png -m 4 > $@
</pre>
</p>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong>Caveats and Future Work</strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<p>
Use the <a href="http://code.google.com/p/bargraphgen/issues/list">Issue
Tracker</a> to see the current list of requested features and reported
bugs. Below is a list of some key issues and future work with my current
script:
<ul>
<li><a name="gnuplot-bug">There is a bug in gnuplot 4.2.0 where scaling
via <tt>set size</tt> clips axis tic labels to their un-scaled bounds. I
have
<a href="gnuplot-4.2.0-setsize-bugfix.diff">a patch</a> that fixes this,
which I also sent to the gnuplot developers. Update: gnuplot 4.2.2, and
gnuplot 4.3 still contain the bug, but the same patch applies.</li>
<p>
Andreas Schiffler has provided instrutions for patching a fink-installed gnuplot on OSX:
<pre>
sudo cp /sw/src/gnuplot-4.2.5.tar.gz .
...untar, patch, retar...
sudo cp gnuplot-4.2.5.tar.gz /sw/src
md5sum gnuplot-4.2.5.tar.gz
sudo vi /sw/fink/10.4/unstable/main/finkinfo/sci/gnuplot.info
...update MD5...
sudo fink rebuild gnuplot
sudo fink reinstall gnuplot
</pre>
</p>
<li>I've tested my latest script on Fedora Core 10's default packages:
<blockquote><tt>transfig-3.2.5-4<br>
gnuplot-4.2.3-1</tt>
</blockquote>
I've tested prior versions of my script on Fedora Core 5's default packages:
<blockquote><tt>transfig-3.2.4-13.3<br>
gnuplot-4.0.0-11</tt>
</blockquote>
As well as a custom install of gnuplot 4.2.0, for bargraph.pl release
version 4.2.
</li>
<li>When using non-default fonts and the legend is outside of the graph
bounds, its bounding box size must be estimated in order to obtain the
correct overall bounding box. I use a hack to do this now that uses a
maximum size per character. Ideally the actual bounding box would be
computed. See also the <a href="#bbfudge">bounding box calculation
hacks</a> used for font changes.</li>
<li>It would be nice to have an option to automatically place a value
label, especially for value beyond a specified maximum. This is Issue
6.</li>
<li>Gnuplot 4.0 now supports filled bar graphs, which
could simplify part of my script. I haven't yet tried out the new
fill support.
</ul>
<!--------------------------------------------------------------------------->
<table bgcolor="#6699cc" width=100% cellspacing=0 cellpadding=5 border=0>
<tr><td> <font size=+2>
<strong>Version History</strong>
</font></td></tr></table>
<!--------------------------------------------------------------------------->
<p>
The full version history is in
the <a href="http://code.google.com/p/bargraphgen">bargraphgen</a> public
repository.
</p>
<dl>
<dt><strong>4.6 -- January 31, 2010</strong><dd><p>Added automatic legend
placement, including automatically finding an empty spot inside the graph.
Added logarithmic y value support. Added control over leading and
intra-bar spacing.
</p></dt>
<dt><strong>4.5 -- January 17, 2010</strong><dd><p>Improved legends with
a filled background and outline and bounding box. Added sorting, horizontal
line drawing, and other features.</p></dt>
<dt><strong>4.4 -- August 10, 2009</strong><dd><p>Added gnuplot 4.3 support
along with miscellaneous options (rotateby=, xticshift=, ylabelshift=,
=stackabs).</p></dt>
<dt><strong>4.3 -- June 1, 2008</strong><dd><p>Added error bar support
along with miscellaneous options (-non-transparent