From: jafortun@vela.acs.oakland.edu (James Fortune)
Subject: Quasi-bar graph technique (long)
Summary: Includes source for general histogram program
Keywords: histogram, ogive, bar graph, TurboPascal
Organization: Oakland University, Rochester MI.
Date: Wed, 7 Oct 1992 19:53:06 GMT

A couple of years ago I was doing some tutoring in statistics and needed
a program that would allow my pupil to change the number of class intervals
to see the effect on the resulting histogram (and ogive).  The program
was written in TurboPascal 3.0 and ran with Gnuplot 2.0.  It would take VERY
little to adapt it to run using, e.g., TurboPascal 6.0.  The main benefit
to readers of comp.graphics.gnuplot is the technique of producing quasi-
bar graphs for the histogram.  The bars are not filled in but the gnuplot
wizards can take care of that.  The user specifies a file containing
numerical data separated by spaces and newlines.  For example,

5.1 6.3 8.7 9.2
7.1 9.3 2.2
8.9
3.2 -2.1 6.6 

The program reads the data, finds the max and min, prompts the user for
the max and min x values and the number of intervals for the histogram.
The program then counts how many values are contained in each class interval
and produces a file with x-y pairs for the quasi-bar graph plot.  It also
creates a gnuplot.ini file that has to be deleted when finished (the student
didn't need to use gnuplot per se).  A file called go.bat was used to
invoke the histogram program and call gnuplot automatically, namely:

histo
gnuplot

I assume that the user will input the file name correctly.  The TurboPascal
Manual describes how to check to ensure that the file exists.  I also wrote
some little programs to create normal data and n-sided dice data to test
out the program.  E-mail me if you want these.  Have fun.

----------------------------histo.pas-----------------------------------
program histo(input, output);
const
  maxinputfilepts = 10001;
  maxclassintervals = 159;
var m,n,i,j,k,max:integer;
var x1,x2,xmin,xmax,interval,yplotmax,zplotmax:real;
var x : array[1..maxinputfilepts] of real;
var y,z : array[1..maxclassintervals] of integer;
var filnam:string[15];
var phile,phile2,phile3:text;

begin
  write('Please input the name of the data file to be read -> ');
  readln(filnam);
  assign(phile,filnam);
  reset(phile);
  i := 1;
  writeln('Reading Input File');
  writeln;
  if not eof(phile) then
   begin
      while not eof(phile) do
       begin
           if not eoln(phile) then
             begin
               read(phile,x[i]);
               if i = 1 then 
                 begin
                   xmin := x[1];
                   xmax := x[1];
                 end;
               if x[i] > xmax then xmax := x[i];
               if x[i] < xmin then xmin := x[i];
               if x[i] = 0 then writeln('Zero i = ', i);
               if eoln(phile) and not eof(phile) then readln(phile);
               i := i + 1;
             end
           else readln(phile);
       end;
   end;
  close(phile);
  m := i - 1;
  writeln('File ',filnam,' contained ',m,' points');
  writeln;
  writeln('The minimum value in the file was: ',xmin:7:3);
  writeln;
  writeln('The maximum value in the file was: ',xmax:7:3);
  writeln;
  write('Please input the Xmin value for the histogram -> ');
  readln(x1);
  write('Please input the Xmax value for the histogram -> ');
  readln(x2);
  write('Please input the number of class intervals for the histogram -> ');
  readln(n);
  assign(phile, 'gnuplot.ini');
  assign(phile2, 'output.his');
  assign(phile3, 'output.ogi');
  rewrite(phile);
  rewrite(phile2);
  rewrite(phile3);
  for j := 1 to n do
    begin
      y[j] := 0;
      z[j] := 0;
    end;
  interval := (x2 - x1) / n;
  writeln;
  writeln('Press any key to continue.');
  repeat
  until KeyPressed;
  clrscr;
  writeln('Computing Class Frequencies');
  for j := 1 to m do
   begin
     k := 0;
     repeat
       k := k + 1;
       if x[j] < x1 + k * interval then y[k] := y[k] + 1;
     until x[j] < x1 + k * interval;
   end;
  max := 0;
  for j := 1 to n do
    if y[j] > max then max := y[j];
  yplotmax := 1.2 * max;
  for j := 1 to n do
    for i := 1 to j do
       z[j] := z[j] + y[i];
  max := 0;
  for j := 1 to n do
    if z[j] > max then max := z[j];
  zplotmax := 1.2 * max;
  clrscr;
  writeln('Writing Plot File');
  writeln(phile, 'set data style lines');
  writeln(phile, 'set nokey');
  writeln(phile, 'set title ',chr(39),
          'Histogram - press any key to continue',chr(39));
  writeln(phile, 'set xlabel ',chr(39),'Class Intervals',chr(39));
  writeln(phile, 'set ylabel ',chr(39),'Class Frequency',chr(39));
  writeln(phile, 'set xrange [',x1-interval:7:3,':',x2+interval:7:3,']');
  writeln(phile, 'set yrange [',0,':',yplotmax:7:3,']');
  writeln(phile, 'plot ',chr(39),'output.his',chr(39));
  writeln(phile, 'set title ',chr(39),
          'Ogive - press any key to exit',chr(39));
  writeln(phile, 'set data style linespoints');
  writeln(phile, 'set xlabel ',chr(39),'Class Intervals',chr(39));
  writeln(phile, 'set ylabel ',chr(39),'Cumulative Class Frequency',chr(39));
  writeln(phile, 'set xrange [',x1-interval:7:3,':',x2+interval:7:3,']');
  writeln(phile, 'set yrange [',0,':',zplotmax:7:3,']');
  writeln(phile, 'plot ',chr(39),'output.ogi',chr(39));
  writeln(phile, 'exit');
  writeln(phile3, x1 - 0.0 * interval:7:3,' ',0);
  for i := 1 to n do
    begin
      writeln(phile2, x1 + (x2 - x1) * (i - 1.0)/n:7:2,' ',0);
      writeln(phile2, x1 + (x2 - x1) * (i - 1.0)/n:7:2,' ',y[i]);
      writeln(phile2, x1 + (x2 - x1) * (i - 0.5)/n:7:2,' ',y[i]);
      writeln(phile2, x1 + (x2 - x1) * (i)/n:7:2,' ',y[i]);
      writeln(phile3, x1 + (x2 - x1) * (i - 0.0)/n:7:2,' ',z[i]);
    end;
  writeln(phile2, x2,' ',0);
  writeln;
  writeln('Loading Graphics Program, please wait . . .');
  close(phile);
  close(phile2);
  close(phile3);
end.
-----------------------------------------------------------------------
JAF
-- 
James Fortune                  - There are many sides to every question
Oakland University             - until you know the truth.  Then there's
jafortun@vela.acs.oakland.edu  - only one.  --  C. S. Lewis
Disclaimer: Not O.U. opinions  -