\author[Sebastian Rahtz]{Sebastian Rahtz\\
Elsevier Science Ltd\\The Boulevard, Langford
Lane\\Kidlington\\
Oxford, UK\\\texttt{s.rahtz@elsevier.co.uk}}\title{An introduction to PSTricks, part 4}
\begin{Article}
This article concludes my look at \PST{}. I hope you have
enjoyed the show! The material has been drawn from a forthcoming book,
entitled \emph{The \LaTeX{} Graphics Companion}, by Michel Goossens,
Sebastian Rahtz and Frank Mittelbach, to be published by Addison
Wesley in 1997. If you have enjoyed \BV{} articles in the last
couple of years on Seminar, colour in \LaTeX, and \PST, you may find
the book of interest.

In this final part, we look briefly at data plotting, and then
conclude with some finished examples of \PST, which are designed
to show the power of the macros in unusual ways.

\section{Data plotting}
\PST\ has a set of high-level tools for common data-plotting
functions; these can read data from external files, in a variety of
formats. We will not tabulate the extra commands or graphical parameters
this time, as they can be easily found in the \PST{} documentation.
The simplest form of data is  a set of comma or white-space delimited
numbers, but values can also be enclosed in braces (\verb|{}|) or
round brackets (\verb|()|). If the data is enclosed in a single
set of \emph{square} brackets (\verb|[]|), and the opening \verb=[= is at the
start of a line, it will be read much faster; however, it will run
\TeX\ out of memory sooner. Data can also be read once, and then
re-used, with the \Lcs{readdata} and \Lcs{savedata} commands. There is
an important distinction between \Lcs{fileplot} or \Lcs{dataplot}
which parse and validate the data in \TeX, and \Lcs{listplot}, which
simply passes the data on to \PS; the latter approach means that there
is no check on \PS\ memory requirements, but has the advantage that
raw \PS\ can be provided to generate or manipulate the data.
Just to complicate matters, use of the \Lcs{PSTtoEPS} command with the
plotting commands can allow for even bigger datasets. An example of
this is given below, in section~\ref{PSTprog}.

It is important to realize that it is up to the user to check the
data extents and scaling; \PST\ does not make the data fit a
predefined plot area, unlike many other packages. Normally, judicious
setting of \PKey{xunit} and \PKey{yunit} will quickly produce nice
results. Axes are generated separately, and there is no provision for
supplying specific labels for axis tick points. It is, on the other
hand, easy to superimpose multiple plots, and use the \PS\ language to
calculate functions, as the following example shows, overlaying
$\sin(x)$, $\sin(x)\cos(x)$ and $\cos(x)$. 

\begin{example*}
\begin{pspicture}(-1,-2.5)(9,2.5)
\psset{xunit=.20mm,yunit=1.75cm}
\psset{plotpoints=50}
\psplot[linestyle=dashed,linecolor=blue]
 {0}{360}{x sin}
\psplot[plotstyle=dots,dotstyle=triangle]
 {0}{360}{x cos}
\psset{plotpoints=200}
\psplot[linecolor=red]{0}{360}
 {x dup sin exch cos mul}
\end{pspicture}
\end{example*}

The next example shows how the \Lcs{psaxes} command can 
be used to create graph frames; in this mode, it obeys the graphical
fill and colour parameters. This picture (showing 
word length ($x$ axis) against occurrences ($y$ axis) in a passage of
Dickens) also shows how the axis labels can be manipulated.

\begin{example*}
\readdata{\foo}{words.dat}
\psset{yunit=.2mm,xunit=4mm}
\begin{pspicture}(-2,-50)(20,250)
\psaxes[axesstyle=frame,dy=50\psyunit,
  Dy=50,tickstyle=bottom,
  fillcolor=gray,fillstyle=solid](1,1)(18,229)
\dataplot[plotstyle=line,linecolor=white]{\foo}
\end{pspicture}
\end{example*}

\PST\ is not designed to be a fully-fledged business graphics package;
its plotting functions are really for simple scientific plots
only. However, it should be clear that the lower-level \PST\ macros,
and \TeX's programmability, make it a good basis for whatever
graphing is needed. 
We conclude this section with a crude pie chart, with the macros and 
some of the data used to create it; note that only
segments above a certain size are labelled --- providing a sensible
label for all elements would involve considerably more care.
\mbox{Denis} \mbox{Girou} has written a generalised pie-chart and bar
chart creation package for \PST\ (under
revision at the time of writing), which can produce very professional
results.

\newcommand\lang[4]{% name, value, percentage, color
 \setcounter{thisval}{\value{lastval}}
 \addtocounter{thisval}{#3}
 \pswedge[fillcolor=#4]{1}{\thelastval}{\thethisval}%
 \setcounter{thishalf}{((\value{thisval}-\value{lastval})/2)+\value{lastval}}
 \ifnum#3>200\rput(1.3;\thethishalf){#1}\fi
 \setcounter{lastval}{\value{thisval}}
}
\bgroup\psset{unit=2.5}
\centerline{\begin{pspicture}(-1.3,-1.3)(1.3,1.3)
\psset{fillstyle=solid}
\degrees[10000]
\SpecialCoor
\setcounter{lastval}{0}
\lang{Romanian}{1}{3}{green}
\lang{Czech}{2}{6}{blue}
\lang{Bulgarian}{4}{11}{green}
\lang{Japanese}{4}{11}{palegreen}
\lang{Dutch}{7}{20}{black}
\lang{Norwegian}{20}{56}{cyan}
\lang{Greek}{26}{73}{magenta}
\lang{Swedish}{34}{95}{lightgray}
\lang{Danish}{46}{129}{white}
\lang{French}{83}{232}{pink}
\lang{Latin}{146}{409}{wheat}
\lang{Russian}{243}{680}{white}
\lang{Italian}{391}{1093}{gray}
\lang{German}{508}{1421}{lightblue}
\lang{unknown}{599}{1676}{red}
\lang{English}{1462}{4085}{yellow}
\end{pspicture}}
\egroup
\begin{sverbatim}
\usepackage{calc,pstcol}
\newcommand{\lang}[4]{% name, value, proportion of
                      % 10000, colour
 \setcounter{thisval}{\value{lastval}}
 \addtocounter{thisval}{#3}
 \pswedge[fillcolor=#4]{1}{\thelastval}{\thethisval}%
 \setcounter{thishalf}{((\value{thisval}-
                           \value{lastval})/2)+
                             \value{lastval}}
 \ifnum#3>200\rput(1.3;\thethishalf){#1}\fi
 \setcounter{lastval}{\value{thisval}}
}
\psset{fillstyle=solid}
\degrees[10000]
\SpecialCoor
\setcounter{lastval}{0}
\lang{Romanian}{1}{3}{green}
\lang{Czech}{2}{6}{blue}
...
\lang{German}{508}{1421}{lightblue}
\lang{unknown}{599}{1676}{red}
\lang{English}{1462}{4085}{yellow}
\end{sverbatim}

\section{\protect\PST\ programming examples}\label{PSTprog}
In the following pictures, we attempt to show some of the range of
\PST\ possibilities, demonstrate the advantages of using a programming
language for drawing pictures, and explore the various tools for
simplifying and modularizing the code to make it more readable. We
are especially glad to acknowledge Denis Girou for his input to this
section, both in personal exchanges and in published examples.

In the first picture, a kite drawing from a child's book of colours and
shapes, notice how the tail is drawn as a curved node connection
between two points, and the bunting is added as labels on that
connection. Use of the node feature means that the calculation of the
line and positions along it are left entirely to
\PST.  It is also worth recalling the basic \PS\ premise that objects
are opaque unless otherwise stated; this means that we can draw a blue
background to the whole picture, and then overlay solid blocks of
colour for the shapes. Some parts of the picture have a regular,
repeating, feature, and we take advantage of this to
draw the rays of sun using the \Lcs{multido} macro; note that we use a
\TeX\ group to localize the effect of the \Lcs{psset} which changes colour
and style.
\verbfile{kite.tex}
%\end{multicols}
\begin{center}
\vspace*{1.5ex}
  \input kite.tex
\vspace*{1.5ex}
\end{center}
%\begin{multicols}{2}
In the next child's picture, we again take advantage of the strikeout
nature of \PS\ blocks of solid colour to draw the cat head as a whole
circle, and superimpose the wall (and on top of that the bricks) so
that we do not worry about creating a precise wedge of just
over a semicircle. \Lcs{rput} is used extensively to place objects at an
angle.  The writing on the bricks demonstrates the importance of
understanding the reference point of objects that are placed. Since
the bricks and their legends are drawn \emph{after} the graffito, they
partly obscure it.  We group objects of similar characteristics
together, and use \TeX's standard grouping to set \PST\ values for the
items in that group. We also break the picture into different
elements, describe each in a separate macro, and group them into
high-level objects.  This technique allows us to built up a library of
objects, and serves to make the final picture description considerably
more readable. The cat sitting on its portion of wall sets its size
according to a parameter, allowing us to reproduce it several times at
different sizes; note how the \Lcs{rput} command resets the coordinate
system, so that the cat is drawn relative to the position of the \Lcs{rput}.

\verbfile{cat.tex}
%\end{multicols}
\vspace*{1.5ex}
\begin{center}
  \input cat.tex
\end{center}
\vspace*{1.5ex}
%\begin{multicols}{2}
The third complete picture is more complex, a
circuit diagram. We have
chosen to make this by programming a small language
for circuit diagrams, which implements the actions
\Lcs{Battery},
\Lcs{Resistor}, \Lcs{Switch} and
\Lcs{Inductor}, with the movement commands
\Lcs{Up},
\Lcs{Down}
\Lcs{Left}, and
\Lcs{Right}  in the spirit of \textsf{pic}.
Thus the final part of the input is quite simple,
apart from the node connection and label commands which are used
in their normal way (some care is needed to consider the angles
at which connection lines leave and join each node).

\begin{sverbatim}
\Up{1}
\Battery{A}
\Up{1}
\Right{2}
\Resistor{B}
\Right{1}
\Down{.3}
\Inductor{C}
\Down{.5}
\Left{1}
\Switch{D}
\ncangle[angleA=90,angleB=180,armB=0]{A}{B}
\ncangle[angleA=0,angleB=90,armB=0]{B}{C}
\ncput[ref=l]{~~~$i=i_{\mbox{max}}(1-w^{-t/3})$}
\ncangle[angleA=-90,armB=0,angleB=0]{C}{D}
\ncangle[angleA=180,armB=0,angleB=-90]{D}{A}
\nput{180}{A}{10V}
\nput{90}{B}{R}
\nput{0}{C}{3mH}
\nput{270}{D}{S}
\end{sverbatim}

\makeatletter 
\newdimen\CurX
\newdimen\CurY \newdimen\Cir@temp
\newcount\Cir@direction % 0 right, 1 left, 2 up, 3 down
\Cir@direction0
\def\SetX#1{\CurX=#1pt}
\def\SetY#1{\CurY=#1pt}
\def\ShowDirection{\typeout{Direction:
 \ifcase\Cir@direction right\or left\or up\or down\fi,
    now at (\strip@pt\CurX,\strip@pt\CurY)}%
}
\def\ShowXY{\message{(\strip@pt\CurX,\strip@pt\CurY)}}

\def\Down#1{\advance\CurY  by -#1\p@\Cir@direction3\ShowDirection}
\def\Up#1{\advance\CurY  by #1\p@\Cir@direction2\ShowDirection}
\def\Left#1{\advance\CurX by -#1\p@\Cir@direction1\ShowDirection}
\def\Right#1{\advance\CurX by #1\p@\Cir@direction0\ShowDirection}
\def\MyBox#1#2{% width,height
 \pssetlength{\Cir@temp}{#1}%
 \rule{\Cir@temp}{\z@}%
 \pssetlength{\Cir@temp}{#2}%
 \rule{\z@}{\Cir@temp}%
}
\def\Point#1{%
\rput(\strip@pt\CurX,\strip@pt\CurY){\pnode{#1}}%
}
\def\Switch#1{%
\message{[Switch] #1}\ShowXY
\relax
\ifcase\Cir@direction % right
   \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode[b]{#1}{%
   \psline(.5,.4)%
   \psarc{<-}{.4}{-10}{70}%
   \MyBox{.5}{.4}%
   }}%
   \advance\CurX by .5\p@
\or % left
   \advance\CurX by -.5\p@
   \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode[b]{#1}{%
   \psline(0,0)(.5,.4)%
   \psarc{<-}{.4}{-10}{70}%
   \MyBox{.5}{.4}%
  }}%
\fi
}

\def\Battery#1{%
\message{[Battery] #1}\ShowXY
\relax
\ifcase\Cir@direction % right
   \rput[r](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{%
     \psline(0,-.4)(0,.4)%
     \psline(.2,-.2)(.2,.2)%
     \MyBox{.2}{.8}%
    }}%
   \advance\CurX by .2\p@
\or % left
   \advance\CurX by -.2\p@
   \rput[r](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{%
     \psline(0,-.4)(0,.4)%
     \psline(.2,-.2)(.2,.2)%
     \MyBox{.2}{.8}%
    }}%
\or % up
   \advance\CurY by .2\p@
   \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{%
     \psline(.1,.2)(.9,.2)%
     \psline(0.3,0)(0.7,0)%
     \MyBox{1}{.2}%
    }}%
\or % down
   \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#1}{%
     \psline(-.4,0)(.4,0)%
     \psline(-.2,-.2)(.2,-.2)%
     \MyBox{1}{.2}%
    }}%
   \advance\CurY by -.2\p@
\fi
}

\def\Resistor{\message{[Resistor]}\ShowXY
  \@ifnextchar[{\@ResInd}{\@ResInd[1]{pszigzag}}}
\def\Inductor{\message{[Inductor]}\ShowXY
  \@ifnextchar[{\@ResInd}{\@ResInd[1]{pscoil}}}

\def\@ResInd[#1]#2#3{%
 \ifcase\Cir@direction % right
   \rput[l](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{%
   \csname #2\endcsname[coilarm=.01,coilwidth=.3](0,.15)(#1,.15)%
   \MyBox{#1}{.3}%
    }}%
   \advance\CurX by #1\p@
 \or % left
   \advance\CurX by -#1\p@
   \rput[l](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{%
   \csname #2\endcsname[coilarm=.01,coilwidth=.3](0,.15)(#1,.15)%
   \MyBox{#1}{.3}%
    }}%
 \or % up
   \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{%
   \csname #2\endcsname[coilarm=.01,coilwidth=.3](.15,0)(.15,#1)%
   \MyBox{.3}{#1}%
    }}%
   \advance\CurY by #1\p@
 \or % down
   \advance\CurY by -#1\p@
   \rput[b](\strip@pt\CurX,\strip@pt\CurY){\rnode{#3}{%
   \csname #2\endcsname[coilarm=.01,coilwidth=.3](.15,0)(.15,#1)%
   \MyBox{.3}{#1}%
    }}%
 \fi
}
\makeatother

\begin{pspicture}(5,5)
\SetX{1}
\Up{1}
\Battery{A}
\Up{1}
\Right{2}
\Resistor{B}
\Right{1}
\Down{.3}
\Inductor{C}
\Down{.5}
\Left{1}
\Switch{D}
\ncangle[angleA=90,angleB=180,armB=0]{A}{B}
\ncangle[angleA=0,angleB=90,armB=0]{B}{C}
\ncput[ref=l]{~~~$i=i_{\mbox{max}}(1-w^{-t/3})$}
\ncangle[angleA=-90,armB=0,angleB=0]{C}{D}
\ncangle[angleA=180,armB=0,angleB=-90]{D}{A}
\nput{180}{A}{10V}
\nput{90}{B}{R}
\nput{0}{C}{3mH}
\nput{270}{D}{S}
\end{pspicture}

The new commands are implemented in terms of a current $x$ and $y$
coordinate, which is changed by the movement commands. Thus \Lcs{Down} is
defined (simplified) in the following code:

\begin{sverbatim}
\newcommand{\Down}[1]{%
  \setcounter{CurY}}{-#1}%
  \def{Cirdirection}{3}%
  }
\end{sverbatim}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure*}[t!]
\centerline{\includegraphics{map.eps}}
\caption{Autocad picture converted to \protect\PST\ macros}
\label{PSTacad}
\end{figure*}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

After each movement the current direction of movement is recorded,
since this affects how we draw the new objects. These have a switch
(which we have simplified in the following code example\footnote{since
we possibly want sizes to be real numbers, \Lcs{CurX} and \Lcs{CurY}
are in fact \TeX\ dimensions, which we convert back to numbers before
use.})  to check direction. The plain \TeX{} \Lcs{ifcase} command is
used to perform a 4-way switch between directions. The definition of
the resistor is:

\begin{sverbatim}
\newcommand{\Resistor}[1]{%
 \ifcase\Cirdirection % right
   \rput[l](\CurX,\CurY){\rnode{#1}{%
   \pszigzag[coilarm=.01,coilwidth=.3](0,.15)(1,.15)%
   \MyBox{1}{.3}}}%
   \addtocounter{CurX}{1}%
 \or % left
   \addtocounter{CurX}{-1}%
   \rput[l](\CurX,\CurY){\rnode{#1}{%
   \pszigzag[coilarm=.01,coilwidth=.3](0,.15)(1,.15)%
   \MyBox{1}{.3}}}%
 \or % up
   \rput[b](\CurX,\CurY){\rnode{#1}{%
   \pszigzag[coilarm=.01,coilwidth=.3](.15,0)(.15,1)%
   \MyBox{.3}{1}}}%
   \addtocounter{CurY}{1}%
 \or % down
   \addtocounter{CurY}{-1}%
   \rput[b](\CurX,\CurY){\rnode{#1}{%
   \pszigzag[coilarm=.01,coilwidth=.3](.15,0)(.15,1)%
   \MyBox{.3}{1}}}%
 \fi
}
\end{sverbatim}

The macro \Lcs{MyBox} is very important; since by itself \Lcs{pszigzag} takes
no space, it will create a node with no width or height, and
connectors will go right to the middle. Therefore we put in some
\LaTeX\ struts with the \Lcs{rule} command, to create an invisible box
around the zigzag. The \PST\ units are converted to normal \TeX\
lengths using \Lcs{pssetlength}.

\begin{sverbatim}
\newlength{\Cirtemp}
\newcommand{\MyBox}[2]{% width,height
 \pssetlength{\Cirtemp}{#1}%
 \rule{\Cirtemp}{0pt}%
 \pssetlength{\Cirtemp}{#2}%
 \rule{0pt}{\Cirtemp}%
}
\end{sverbatim}


Our final example takes \PST\ into another subject area, that of
cartography. The map in Figure~\ref{PSTacad} is created from
an Autocad DXF file; this time the 36
polygons, comprising 9619 separate line segments, were converted
(using a simple \emph{ad hoc} conversion program) to a separate
coordinate data file for each polygon. The overall map description
consists simply of 36 lines of the form:
\begin{sverbatim}
\ProcessVector{moh174}
\ProcessVector{moh170}
\end{sverbatim}
Since the number of coordinates is so large, many of the \PST\ tools
which can read the files (like \Lcs{fileplot}) run out of \TeX\ memory;
however, for purely graphical objects like polygons, we have the 
more efficient and less memory-intensive option of writing
Encapsulated \PS\ files on the fly, so we instantiate the
\Lcs{ProcessVector} lines with the definition:
\begin{sverbatim}
\newcommand{\ProcessVector}[1]{%
 \PSTtoEPS{#1.eps}{\fileplot{#1.dat}}
 \rput(0,0){\includegraphics{#1.eps}}%
}
\end{sverbatim}
The command \Lcs{PSTtoEPS} takes two arguments, a filename, and any
pure \PST\ commands (\ie not text). Instead of embedding the necessary
\PS\ as \Lcs{special}s in the \TeX\ output, a \PS\ file is written
directly.

Using the very simple top level \Lcs{ProcessVector} command means that the
master file is easily hand-edited; since the Autocad file identifies
the polygons by their `layer' (the map is a set of contour lines), we
are able to set the fill colour separately for each layer, and so
produce the more traditional map.
\end{Article}
