\makeatletter
\def\MP{MetaPost}
\def\foreign{\em}
\def\eg{{\foreign e.g.~}\ignorespaces}          % e.g.
\DeclareRobustCommand\META{\textlogo{META}}
\newsavebox{\boxdef}
   \newenvironment{BDef}{\begin{lrbox}{\boxdef}\def\arraystretch{1.0}%
      \begin{tabular}{@{}l@{}l@{}l@{}}}%
    {\end{tabular}\end{lrbox}%
     \BCmd\fbox{\usebox\boxdef}\endBCmd}    % i hate this whole coding section!
\newenvironment{BCmd}{\@beginparpenalty-\@lowpenalty\fboxsep=3pt\flushleft}
                       {\@endparpenalty\@M\@topsepadd 10pt\relax \endflushleft}
\makeatother
\def\Mpack#1{\texorpdfstring{\textsf{#1}}{#1}}
\let\Lpack\textsf
\let\Mmpack\textsf
\let\Mcmd\texttt
\let\mMcmd\texttt
\let\Author\relax
\def\Program#1{\textsf{#1}}
\let\mMPcmd\texttt
\let\MPcmd\texttt

\def\PreambleCommands{input graph}
\title{A tutorial on using \MP's \Mpack{graph} package}
\author[Sebastian Rahtz]{Sebastian Rahtz\\7 Stratfield Road\\Oxford OX2 7BG\\UK\\\texttt{s.rahtz@elsevier.co.uk}}

\begin{Article}
\section{Introduction}

\MP{} is a sibling program to \MF, which replaces the bitmap output of
the latter with PostScript and is designed more as a general-purpose
drawing language than a font creation package.  Although it has been
around for five years or so (it has been  Don Knuth's tool of choice for
drawing for some time), it has only recently started becoming
generally available for most users. With the release of Web2c version
7.0, \MP{} is integrated into the standard Unix and Windows 32 \TeX{}
distribution, and it is also part of the CMacTeX and OzTeX packages
for the Macintosh.

Although many people find general-purpose drawing languages quite
forbidding and counter-intuitive, creating nice graphs from simple
data files is a common task, and the purpose of this short
tutorial\footnote{This material is taken from chapter 3 of \emph{The \LaTeX{}
    Graphics Companion}, by Michel Goossens, Sebastian Rahtz and Frank
  Mittelbach, published by Addison-Wesley in March 1997. Reprinted by
permission of Addison-Wesley.} about \MP{}
is to describe its graphing support.  The high-level library of \MP{}
macros to draw graphs was written by \MP's author, John Hobby, to
provide a sophisticated interface comparable to \Program{grap}
(see Bentleyand Kernighan, 1984).  It is hoped that by giving
examples of its use, more people can be encouraged to try it and (who
knows?) start to explore more of \MP{} for other sorts of drawing.

\MP{} is well documented in Hobby (1992), and the graph package
is described in Hobby (1993); both these documents normally form part
of a \MP{} distribution.

\section{Getting started}
To start, a quick recipe for writing a \MP{} input file.
Unlike \TeX, there are no backslashes or curly braces, and commands
normally end with semicolons; at the start of your file, you need to
load the \texttt{graph} package with an \texttt{input} command, and
the file is completed with \texttt{end;}. In between you can have one or more
drawings inside \texttt{beginfig}\ldots \texttt{endfig;}, where
\texttt{beginfig} has a parameter (in round brackets) of
a number which will be the suffix of the output PostScript file. A
graph comes inside \texttt{draw begingraph} \ldots \texttt{endgraph;},
where \texttt{begingraph} has a parameter of two dimensions which set
the width and height of the graph. \MP{} takes care of scaling all the
drawing to fit in this area. Thus a complete \MP{} file might look
like this:
\begin{sverbatim}
input graph
beginfig(1)
draw begingraph(2.5in,1.75in);
gdraw "yearm.dat";
endgraph;
endfig;
end;
\end{sverbatim}
If we save this  as \texttt{test.mp}, and run it with the command
\texttt{mpost test.mp}, the output (under Unix) looks something like
this:
\begin{fverbatim}
darkstart:~/# mpost test.mp
This is MetaPost, Version 0.632 (Web2c 7.0)
(test.mp (/cdrom/share/texmf/metapost/base/graph.mp
(/cdrom/share/texmf/metapost/base/marith.mp
(/cdrom/share/texmf/metapost/base/string.mp))
(/cdrom/share/texmf/metapost/base/format.mp
(/cdrom/share/texmf/metapost/base/string.mp)
(/root/tds/metapost/latexpp/texnum.mp))) [1] )
1 output file written: test.1
Transcript written on test.log.
\end{fverbatim}
Labels or captions in a \MP{} drawing are often passed to \TeX{} to
process behind the scenes, as we shall see presently, and the result
is a PostScript file we can include in our \TeX{} in the ordinary
way. It is assumed that the reader can find out how to do this.

Rather than showing the trivial result of that test, let us
consider a slightly more sophisticated real
graph (using data from the Protestant Cemetery, 
Rome---see Rahtz (1988)) which looks like this (henceforth we
only show the \MP{} code between \texttt{begingraph} and
\texttt{endgraph}):
\begin{MPExample*}{}
draw begingraph(2.5in,1.75in);
gdraw "yearm.dat" dashed evenly;
gdraw "yearw.dat";
glabel.lft 
 (btex (solid) Women etex, 1960,30);
glabel.lft 
 (btex (dashed) Men etex ,1870,30);
glabel.bot 
 (btex Number of burials per year 
 ($n \approx 4300$) etex,OUT);
endgraph;
\end{MPExample*}
This shows some of the main features of the \Mpack{graph} package for
plotting data from external data files and labeling. The command
\texttt{gdraw} (which can be used several times in succession) is
followed by a file name; it reads data values (two per line, giving an
$x$ and $y$ coordinate) from that file, and plots the resulting line.
The effect can be varied with various modifiers --- here we used
\texttt{dashed evenly}.  The command \texttt{glabel}, to place some
captioning text, has a prefix (separated by .) which indicates where
on the graph it is to go (\texttt{lft} = `left', \texttt{bot} =
`bottom' etc). It is followed by an expression inside round brackets
of text, an $x$ coordinate, and a $y$ coordinate. The special
coordinate pair of \texttt{OUT} means it will be placed neatly outside
the graph area. You can supply literal text in quotes, or have it
processed by \TeX{} by bracketing it with \texttt{btex} \ldots
\texttt{etex} (no quotes around the text in this case).

The \texttt{graph} package can  take care of:
\begin{itemize}
\item automatic scaling of data;
\item automatic generation and labeling of tick marks or grid lines;
\item multiple coordinate systems in the same picture;
\item linear and logarithmic scales;
\item plotting with arbitrary symbols;
\item handling multiple columns in the same data file, with
 user-specified procedures.
\end{itemize}

\section{Variations in basic graphing}
If \Mcmd{gdraw} is followed by a \mMcmd{plot} command, a symbol can be
drawn at each coordinate instead of a continuous line; the symbols is
technically a \MP{} ``picture'', i.e. in practice some text which
can be typeset by \TeX, as the following variation shows:%
\begin{MPExample*}{}
draw begingraph(2.5in,1.75in);
gdraw "yearm.dat" 
 plot btex $\bullet$ etex;
gdraw "yearw.dat" 
 plot btex $\circ$ etex;
glabel.bot 
 (btex Burials etex,OUT);
glabel.lft
 (btex Number etex rotated 90,OUT);
endgraph;
\end{MPExample*}
For this graph we also rotated the label for the $y$ axis by
90\textdegree{} using a modifier to \texttt{btex} \ldots
\texttt{etex}.

\subsubsection{Frames, ticks, grids and scales}
By default, graphs have a frame on all sides, 
no grid, and tick marks on the bottom and left. 
The frame can be altered with the \mMcmd{frame} command, which has 
a set of optional suffixes. Grid lines and ticks are controlled with
\Mcmd{autogrid}:
\begin{BDef}
\mMcmd{autogrid}(\emph{$x$ specification},\emph{$y$ specification})
\end{BDef}
\noindent The specifications can have the values \mMcmd{grid}, 
\mMcmd{itick} or
\mMcmd{otick}, which produce grid lines, inner ticks, or outer ticks;
they can be suffixed with \texttt{.top} or \texttt{.bot} for the $x$ axis
and \texttt{.lft} and \texttt{.rt} for the $y$ axis, as the following
example shows:
\begin{MPExample*}{}
draw begingraph(2.5in,1.75in);
gfill "yearw.dat" withcolor red;
autogrid(grid.bot,itick.rt) 
  withcolor .5white;
frame.llft;
endgraph;
\end{MPExample*}
To override \Mpack{graph}'s choice of where to put tick
marks and how to write labels, you can add explicit ticks with
\mMcmd{itick} or \mMcmd{otick} 
and grid lines with \mMcmd{grid}. 
These have the same suffixes as \Mcmd{autogrid} and are
followed by a \MP{} picture variable containing a label or a
\Mcmd{format} command, and a coordinate. \Mcmd{format}
is used to control how numbers are printed:
\begin{BDef}
\mMcmd{format}(\emph{specification},\emph{number})
\end{BDef}
\noindent The \emph{specification} consists of 
an optional initial string, a percent sign,
an optional number indicating precision (default 3), a conversion
letter (\texttt{e}, \texttt{f} or \texttt{g}) and an optional final string.
The conversion letter determines whether or
not scientific notation is used; 
\texttt{\%g} will use decimal format for most numbers. How
the scientific notation used by \Mcmd{format} is typeset depends on a
\MP{} macro called \Mcmd{init\_numbers} (see manual); since this uses
the \MPcmd{btex}\ldots\MPcmd{etex} system, you may need to look at it
carefully if you are concerned about precisely which fonts are used.


The next graph shows both types of explicit labeling; 
we have to remember to turn off the normal marks at the end!%
\begin{MPExample*}{}
draw begingraph(2.5in,1.75in);
gfill "yearw.dat" withcolor red;
for y=10,20,30: 
  itick.lft(format("%g",y),y);
endfor
otick.top("19th century",1850);
otick.top("20th century",1950);
frame.llft;
autogrid(,);
endgraph;
\end{MPExample*}
The labeling can also be changed by \Mcmd{setcoords}
\begin{BDef}
\mMcmd{setcoords}(\emph{$x$ style},\emph{$y$ style})
\end{BDef}
The parameters for $x$ and $y$ can be set to
\texttt{log}, \texttt{-log}, \texttt{linear}, or \texttt{-linear}.

While the program's scaling of data to fit the graph usually gives the right
results, it can be overridden with \Mcmd{setrange}:
\begin{BDef}
\mMcmd{setrange}(\emph{min},\emph{max})
\end{BDef} 
You need to supply the minimum and maximum coordinates.
The special constant
\mMcmd{origin} is a useful shorthand for (0,0). 
To leave any value to be figured out
by \MP, specify \mMcmd{whatever}. If you specify no range
at all, \MP{} works it out from the data values and adds a small
border.

\subsubsection{Reading data files}
Although the \Mcmd{gdraw} and \Mcmd{gfill} commands often suffice, we
can get more control over the data read from a file by using \Mcmd{gdata}: 
\begin{BDef}
\mMcmd{gdata}(\emph{filename}, \emph{variable}, \emph{commands})
\end{BDef}
The \emph{commands} are executed for every line of data in
\emph{filename},  with the values for each column available as, \eg $c1$, $c2$
\ldots $c\mbox{n}$ for the variable name $c$. \emph{filename} is a
\META{} string, so simple names should be enclosed in quotes (file
names can also be computed from \META{} variables.) Using some more data
from the Protestant Cemetery in which each line consists of a person's
age at death, we can show the distribution of mortality by age by
accumulating data in an array and using that to create a path:%
\begin{MPExample*}{}
draw begingraph(2.5in,1.5in);
numeric p[]; path r;
for j := 0 upto 100: p[j]:=0; endfor 
gdata ("ages.dat",y, age:=(scantokens y1);
 p[age]:=p[age] + 1;);
r:=(0,0) 
 for j := 1 upto 100: --(j,p[j]) endfor;
gdraw r;
frame.llft;
endgraph;
\end{MPExample*}
The only complications are the need to initialize the array and
the conversion of the string representation read from the data file
into a numeric value with \mMPcmd{scantokens}.

When \mMcmd{gdata} reads data files, it stops when it reaches a blank
line or end of file; if you start \Mcmd{gdata} again with the same
file name, it carries on reading another set of data. This allows you
to put all your data sets in one file, but use it with care. One
problem is that data files remain open if there is a blank line at the
end, since \MP{} thinks some more data might follow; if you have many
small data files, this situation can cause a \MP{} error---check the
end of your files.

This display in the example above is not very readable; it might be
better to accumulate data per decade of death from the file. As this
gets a little more complicated, we abstract the job into a \MP{} macro
called by the \Mcmd{gdata} command:
\begin{MPExample*}{}
draw begingraph(2.5in,1.75in);
setrange(origin,(100,100));
numeric p[]; path r;
for j := 0 step 10 until 100: 
  p[j]:=0; endfor 
def check(expr age) =
 if age < 100: 
   xage:=round(age/10) * 10;
   p[xage]:=p[xage] + 1; fi
enddef;
gdata ("ages.dat",y, 
  check((scantokens y1)););
r:=(0,0) for j := 0 step 10  until 100: 
   --(j,p[j]) endfor --(100,0);
gfill r -- cycle withcolor blue;
frame.llft;
endgraph;
\end{MPExample*}

It is often useful to accumulate points on a path for each line
read from the data file; the macro \mMcmd{augment} is provided for
this. Given a suffix of a variable name of type ``path'' and a
parameter of a coordinate, \Mcmd{augment} 
creates the path if it does not exist
or adds the point to an existing path. We use this to show the
gravestone data again, this time processed to provide separate
figures of deaths per decade for women (column 2) and men (column~3):
\begin{verbatim}
1800 3 6
1810 9 15
1820 26 64
1830 31 88
...
\end{verbatim}
For each decade, we keep track of the last point reached and augment
separate paths for male and female; these are then shaded in different
colors to show how the
male and female patterns vary over time. We need to know the last
decade in order to establish a sensible corner for the filled shape.
The female pattern appears as a dotted line on top of the male
shading.
\begin{MPExample*}{}
path m,w,last;
draw begingraph(3in,2in);
setrange((1800,0),(whatever,whatever));
gdata ("decade.dat",y, 
  last:=((scantokens y1),0);
  augment.w(y1,y2);
  augment.m(y1,y3););
gfill (1800,0)--w--last--cycle 
  withcolor red;
gfill (1800,0)--m--last--cycle 
  withcolor green;
pickup pencircle scaled 3pt;
gdraw w dashed withdots;
pickup pencircle scaled .75pt;
glabel.bot (btex Number of burials per decade 
     ($n \approx 4300$) etex,OUT);
endgraph 
rotated 90;
\end{MPExample*}
The example demonstrates that the graph macros return a \META{}  picture
that can then be transformed (in this case rotated).

\subsubsection{Different graph types}
With a little effort, \Mpack{graph} can draw bar charts; 
to demonstrate this, we copy a chart from
Goossens et~al.\ (1994), p.~287, that was made with the \LaTeX{} \Lpack{bar}
package. Our technique is to make a single path out of all the bars
and fill the result at the end:%
\begin{MPExample*}{}
path s; numeric x,y;
draw begingraph(2.5in,1.75in);
gdata ("students.dat",c,
 x:=(scantokens c1) * 12;
 y:=(scantokens c2);
 augment.s((x-5,0)--
 (x-5,y)-- (x+5,y)--
 (x+5,0));
 if y < 0: glabel.top(c2,(x,0)); fi
 if y > 0: glabel.bot(c2,(x,0)); fi
);
gfill s--cycle withcolor .5white;
frame.llft;
endgraph;
\end{MPExample*}
\noindent We explicitly work out the corners of each bar and allow for
their width by multiplying the $x$ values by 12; the bars
themselves span 5 units on either side of the data point, so there is a
gap of 2 units between each one.

A similar technique is used in the next chart which shows the number
of pages in chapters of \emph{The \LaTeX{} Graphics Companion};
this time we draw each bar separately, so that they can be shaded
according to the values. The work is delegated to a macro, which also
prints a rotated label for each bar. Because explicit $x$ labels are
supplied, labeling of the $x$ axis is suppressed.
\begin{MPExample*}{}
path m; numeric n,width;
width:=20; defaultscale:=0.6; n:=0;
def bar(expr name,value) =
 gfill(n,0)--(n,value)--
 (n+width,value)--(n+width,0)--cycle
 withcolor (value/100,value/100,value/100);
 picture p;
 p = name infont defaultfont 
     scaled defaultscale rotated 90;
 glabel.rt
   (image(unfill bbox p; draw p),(n,10));
 n:=n+width;
enddef;
draw begingraph(2.5in,1.75in);
setrange((0,0),(11*width,100));
autogrid(,otick.lft);
gdata("chap.dat",c,bar(c1,(scantokens c2)););
endgraph;
\end{MPExample*}
The string value read from the first data column is put into a
\MP{} picture variable by using the low-level command \mMPcmd{infont}.
This lets us use \MPcmd{bbox} technique to give the extent of the
text, which is made white with \MPcmd{unfill}. 
\mMPcmd{image} is a useful macro that
yields the picture resulting from a sequence of drawing commands; we
use that as a label. The data for this graph starts as follows:
\begin{verbatim}
graphics 28
stdgraph 26
xypic 28
mf 26
...
\end{verbatim}

We can also present our earlier ``decade'' data 
as a dual bar chart, with male and female figures side by side. To do
this we maintain two separate paths, fill one and leave the other as
an outline:
\begin{MPExample*}{}
path m[],w[];
def wcheck(expr decade,value) =
 augment.w1(decade,0);
 augment.w1(decade,value);
 augment.w1(decade+5,value);
 augment.w1(decade+5,0);
enddef;
def mcheck(expr decade,value) =
 augment.m1(decade+5,0);
 augment.m1(decade+5,value);
 augment.m1(decade+10,value);
 augment.m1(decade+10,0);
enddef;
draw begingraph(3.75in,2in);
gdata ("decade.dat",y, 
  wcheck((scantokens y1),(scantokens y2));
  mcheck((scantokens y1),(scantokens y3)););
gfill m1--cycle;
gdraw w1;
glabel.bot (btex Number of burials per decade 
     ($n \approx 4300$) etex,OUT);
frame.llft;
endgraph rotated 90;
\end{MPExample*}

With care, we can even draw pie charts using similar
ideas. The following example \label{mppie} reads data about gravestones in the
Protestant Cemetery in the following form:
\begin{verbatim}
Romanian 1 0.02796420582
Czech 2 0.05592841163
.....
Italian 391 10.93400447
German 508 14.20581655
unknown 599 16.75055928
English 1462 40.8836689
\end{verbatim}
\noindent Here the second column is the number of gravestones per
nationality and, to make the code less complicated, the third column is the
percentage of the total. For each pie wedge, we use
the \mMPcmd{buildcycle} macro to find the smallest enclosed shape from
the union of a whole circle and two lines extending from the center at
the starting and closing angle of the segment. The fill color of the
wedge is derived from the percentage.
\begin{MPExample*}{}
numeric r,last; path c,w;
r:=5; c:=fullcircle scaled 2r;
last:=0.0;
def wedge (expr lang,value,perc) =
 numeric current,n,half,xoff,yoff;
 picture p;
 n:=perc*3.6;
 current:=last+n;    half:=last+(n/2);
 w:=buildcycle((0,0)--(2r,0) rotated last, 
  c, (2r,0)--(0,0) rotated current);
 gfill w withcolor
   (0.8-(perc/100),0.8-(perc/100),0.8-(perc/100));
 gdraw w;
 if perc > 5:
 p = lang infont defaultfont 
    scaled defaultscale;
 glabel(image(unfill bbox p; draw p),
  3/4r*dir(half));
 fi;
 last:=current;
enddef;
draw begingraph(3in,3in);
defaultscale:=0.7;
gdata ("langs.dat",c,
  wedge(c1, (scantokens c2), 
   (scantokens c3)););
autogrid(,);  frame withcolor white;
endgraph;
\end{MPExample*}
The placement of the labels in the pie bears a
little examination; they are placed in the center of each wedge, three quarters
of way along the radius. 

Another type of graph has a linear $x$ scale and uses the $y$ axis
simply to compare sets of data. The following graph uses our
cemetery data to show the first and last occurrences of each type of
gravestone. The code is straightforward 
except that we draw the lines
with a different sized pen (with square ends) and revert
to a thin line to draw the scale and frame (only on the bottom, since
the $y$ axis is not linear).
\begin{MPExample*}{}
draw begingraph(2.5in,2.5in);
n:=10;
defaultscale:=0.7;
pickup pensquare scaled 3pt;
setrange((1700,0),(whatever,whatever));
gdata("stones.dat", s, 
gdraw ((scantokens s2),n)--
  ((scantokens s3),n);
glabel.lft(s1,(scantokens s2)-3,n);
n:=n+16;);
pickup pensquare scaled .5pt;
frame.bot;
autogrid(otick.bot,);
endgraph;
\end{MPExample*}
The data, ranked in order of first occurence, starts like this:
\begin{verbatim}
Chest 1738 1966
Head 1765 1986
Column 1766 1960
Plaque-on-base 1775 1986
Pedestal 1786 1967
Plaque-in-ground 1794 1985
\end{verbatim}

Our last example
is more unusual. We want to plot data from a survey
grid and shade each grid square according to its data value; in the data
file the first two columns are the coordinates of the lower left
corner of the grid square, the third column is the absolute data
value, and the fourth column is a percentage version:
\begin{verbatim}
2 1 102 85
2 2 10 98
2 3 110 84
2 4 112 83
2 5 114 83
...
\end{verbatim}
The text is printed in white or black depending on the percentage.
\begin{MPExample*}{}
def sq(expr x,y,num,perc) =
 gfill(x,y)--(x+10,y)--
  (x+10,y+10)--(x,y+10)--cycle
 withcolor (perc/100,perc/100,perc/100);
 glabel(num,(x+5,y+5)) 
   if perc < 50: withcolor white  fi; 
enddef;
defaultscale:=0.7;
draw begingraph(70mm,80mm);
setrange((20,10),(110,110));
autogrid(,);
gdata ("pot.dat",c,
 sq((scantokens c1)*10,
 (scantokens c2)*10,
 c3, (scantokens c4)););
endgraph;
\end{MPExample*}

\begin{thebibliography}{99}
\bibitem{Bentley/Kernighan:1984}
Bentley, J. and Kernighan, B. 1984.
\newblock \emph{{GRAP} --- a language for typesetting graphs}.
\newblock Computing Science Technical Report 114, AT\&T Bell Laboratories,
  Murray Hill, NJ.

\bibitem{Companion}
Goossens, M., Mittelbach, F. and Samarin, A. 1994.
\newblock \emph{The {\LaTeX} companion}.
\newblock Reading, MA: Ad{\-d}i{\-s}on-Wes{\-l}ey.

\bibitem{Hobby:MP}
Hobby, J.~D. 1992.
\newblock \emph{A user's manual for MetaPost}.
\newblock Computing Science Technical Report 162, AT\&T Bell Laboratories.

\bibitem{Hobby:MPG}
Hobby, J.~D. 1993.
\newblock \emph{Drawing graphs with MetaPost}.
\newblock Computing Science Technical Report 164, AT\&T Bell Laboratories.

\bibitem{Rahtz:1988}
Rahtz, S. 1987.
\newblock The Protestant Cemetery, Rome: a study undertaken under the auspices
  of the Unione Internazionale degli Istituti di Archeologia, Storia e Storia
  dell'Arte in Roma.
\newblock \emph{Opuscula Romana}, \textbf{16}, 149--167.

\end{thebibliography}
\end{Article}
