\chapter {Advanced Use of PLPLOT}\label{advanced}

In this chapter, we describe more precisely how to control the position
and scaling of a graph, how to alter the low-level line and character
attributes, and how to use the functions in PLPLOT for drawing 
three-dimensional surface plots and contour plots. 

\section {Basic PLPLOT Concepts}

When drawing a graph, the programmer usually wishes to specify the
coordinates of the points to be plotted in terms of the values of the
variables involved. These coordinates are called {\em world
coordinates}, and may have any floating-point value representable by the
computer. The {\em window} refers to the rectangular region of
world-coordinate space which is to be graphed. This window is mapped
onto a rectangular region of the {\em view surface}, which is (a
portion) of the screen or sheet of paper in the output device. This
physical region onto which the window is mapped is called the {\em
viewport}. Before a graph can be drawn, the program must define both the
window and the viewport by calling appropriate routines in PLPLOT.

\section {Specifying the View Surface}

The first thing that a graphics program must do is to tell PLPLOT which
device it is going to use, and how this device is to be divided up for
graph plotting. There are two routines that do this, \rou{plstar}, which
prompts at the console for the output device type and \rou{plbeg}, which
expects to be supplied the code number of the device as an argument. The
code numbers required by {\tt plbeg} are the same as displayed by {\tt
plstar} when it prompts for a device.

Besides selecting the device, {\tt plstar} and {\tt plbeg} allow the
user to divide the output device plotting area into several subpages of
equal size, each of which can be used separately. The routine {\tt
pladv} is used to advance to a particular subpage or to the next
subpage. The screen is cleared (after waiting for the user to select
Continue from the Graphics Control menu or hit the RETURN key), 
or a new piece of paper is loaded, if a
new subpage is requested when there are no subpages left on the current
page. When a page is divided into subpages, the default character,
symbol and tick sizes are scaled inversely as the square root of the
number of subpages in the vertical direction.

At the end of a plotting program, it is important to close the plotting
device by calling \rou{plend}. This flushes any
internal buffers and frees any memory that may have been allocated.
Note that if {\tt plstar} 
or {\tt plbeg} is called more than once during a program to
change the output device, an automatic call to {\tt plend} is made
before the new device is opened.

\section {Defining the Viewport} \label{viewport}

After defining the view surface, it is necessary to define the portion
of this surface which is to be used for plotting the graph. All lines
and symbols (except for labels drawn by {\tt plbox}, {\tt plmtex} and 
{\tt pllab}) are clipped at the viewport boundaries.

Viewports are created within the current subpage. If the division of the
output device into equally sized subpages is inappropriate, it is best
to specify only a single subpage which occupies the entire output device
(by setting {\tt nx=1} and {\tt ny=1} in {\tt plbeg} or {\tt plstar}),
and use one of the viewport specification subroutines below to place the
plot in the desired position on the page.

There are two methods for specifying the viewport size, using the
subroutines \rou{plvpor} and \rou{plsvpa}. Each of these has the format:
\begin{verbatim}
plvpor(xmin,xmax,ymin,ymax);
plsvpa(xmin,xmax,ymin,ymax);
\end{verbatim}
where in the case of {\tt plvpor}, the arguments are given in {\em
normalized subpage coordinates} which are defined to run from 0.0 to 1.0
along each edge of the subpage. Thus for example,
\begin{verbatim}
plvpor(0.0,0.5,0.5,1.0);
\end{verbatim}
uses the top left quarter of the current subpage.

In order to get a graph of known physical size, the routine {\tt plsvpa}
defines the viewport in terms of absolute
coordinates (millimetres) measured from the bottom left-hand corner of
the current subpage. This routine should only be used when the size of
the view surface is known, and a definite scaling is required.

To help the user call {\tt plsvpa} correctly, the routine \rou{plgspa}
is provided which returns the positions of the extremities of the
current subpage measured in millimetres from the bottom left-hand corner
of the device. Thus, if to set up a viewport with a 10.0~mm margin
around it within the current subpage, the following sequence of calls
may be used 
\begin{verbatim}
plgspa(xmin,xmax,ymin,ymax);
plsvpa(10.0,xmax-xmin-10.0,10.0,ymax-ymin-10.0);
\end{verbatim}
A further routine \rou{plvsta} is available which sets up a standard
viewport within the current subpage with suitable margins on each side
of the viewport. This may be used for simple graphs, as it leaves enough
room for axis labels and a title. This standard viewport is that used by
{\tt plenv} (see Section \ref{plenv-sec}).

\section {Defining the Window} \label{window}

The window must be defined after the viewport in order to map the world
coordinate rectangle into the viewport rectangle. The routine
\rou{plwind} is used to specify the rectangle in world-coordinate space.
For example, if we wish to plot a graph showing the collector current
$I_C$ as a function of the collector to emitter voltage $V_{CE}$ for a 
transistor where $0\le I_C\le 10.0\mbox{\,mA}$ and $0\le V_{CE}\le
12.0\mbox{\,V}$, we would call the function {\tt plwind} as follows:
\begin{verbatim}
plwind(0.0,12.0,0.0,10.0);
\end{verbatim}
Note that each of the arguments is a floating point number, and so the
decimal points are required. If the order of either the X~limits or
Y~limits is reversed, the corresponding axis will point in the opposite
sense, (i.e., right to left for X and top to bottom for Y). The window
must be defined before any calls to the routines which actually draw the
data points. Note however that {\tt plwind} may also be called to change
the window at any time. This will affect the appearance of objects drawn
later in the program, and is useful for drawing two or more graphs with
different axes on the same piece of paper.

\section {Anotating the Viewport}

The routine \rou{plbox} is used to specify whether a frame is drawn around
the viewport and to control the positions of the axis subdivisions and 
numeric labels. For our simple graph of the transistor characteristics,
we may wish to draw a frame consisting of lines on all four sides of the
viewport, and to place numeric labels along the bottom and left hand side.
We can also tell PLPLOT to choose a suitable tick interval and
the number of subticks between the major divisions based upon the
data range specified to {\tt plwind}. This is done using the following
statement
\begin{verbatim}
plbox("BCNST",0.0,0,"BCNSTV",0.0,0);
\end{verbatim}
Another routine \rou{pllab} provides for text labels for the bottom,
left hand side and top of the viewport. These labels are not clipped,
even though they lie outside the viewport (but they are clipped at the
subpage boundaries). {\tt pllab} actually calls the more general routine
{\tt plmtex} which can be used for plotting labels at any point relative
to the viewport. For our example, we may use
\begin{verbatim}
pllab("V\\dCE\\u (Volts)","I\\dC\\u (mA)","TRANSISTOR CHARACTERISTICS");
\end{verbatim}
Note that \verb+\\d+ and \verb+\\u+ are escape sequences (see page 
\pageref{escape}) which allow
subscripts and superscripts to be used in text. They are described more
fully later in this chapter.

The heights of characters used for the axis and graph labels can be
changed by means of the routine \rou{plschr}.

\section {The routine {\tt plenv}}\label{plenv-sec}

Having to call {\tt pladv}, {\tt plvpor}, {\tt plwind} and {\tt plbox}
is excessively cumbersome for drawing simple graphs. Subroutine {\tt plenv}
combines all four of these in one subroutine, using the
standard viewport, and a limited subset of the capabilities of {\tt plbox}.
For example, the graph described above could be initiated by the call:
\begin{verbatim}
plenv(0.0,12.0,0.0,10.0,0,0);
\end{verbatim}
which is equivalent to the following series of calls:
\begin{verbatim}
pladv(0);
plvsta();
plwind(0.0,12.0,0.0,10.0);
plbox("BCNST",0.0,0,"BCNSTV",0.0,0);
\end{verbatim}

\section {Setting Line Attributes}

The graph drawing routines may be freely mixed with those described in
this section which allow the user to control line colour and styles. The
attributes set up by these routines apply modally, i.e, all subsequent
objects (lines, characters and symbols) plotted until the next change in
attributes are affected in the same way. The only exception to this rule
is that characters and symbols are not affected by a change in the line
style, but are always drawn using a continuous line.

Line colour \label{colour} is set using the routine \rou{plcol}. The
argument is ignored for devices which can only plot in one colour but some
terminals support line erasure by plotting in colour zero. For HP
plotters, these colours map to the various pens.

Line style \label{style} is set using the routine \rou{plstyl}. A broken
line is specified in terms of a repeated pattern consisting of marks
(pen down) and spaces (pen up). The arguments to this routine consist of
the number of elements in the line, followed by two pointers to
integer arrays specifying
the mark and space lengths in micrometres. Thus a line consisting of
long and short dashes of lengths 4\,mm and 2\,mm, separated by spaces of
length 1.5\,mm is specified by:
\begin{verbatim}
MARK[0]=4000;
MARK[1]=2000;
SPACE[0]=1500;
SPACE[1]=1500;
plstyl(2,MARK,SPACE);
\end{verbatim}
To return to a continuous line, just call {\tt plstyl} with first argument 
set to zero.

\section {Setting Character and Symbol Attributes}

The routine \rou{plfont} sets up the default font for all character
strings. It may be over-ridden for (a portion) of a string by using an
escape sequence within the text, as described below. Four
fonts are available, the default font (1) is simple and fastest to draw,
while the others are useful for presentation plots on a high-resolution
device.

The font codes are interpreted as follows:
\begin{itemize}
   \item{\tt font = 1}: normal simple font
   \item{\tt font = 2}: roman font
   \item{\tt font = 3}: italic font
   \item{\tt font = 4}: script font
\end{itemize}

The routine \rou{plschr} is used to set up the size of subsquent
characters drawn. The actual height of a character is the product of the
default character size and a scaling factor. If no call is made to
{\tt plschr}, the default character size is set up depending on the number 
of subpages defined in the call to {\tt plstar} or {\tt plbeg}, and the
scale is set to 
1.0. Under normal circumstances, it is recommended that the user does not
alter the default height, but simply uses the scale parameter. This can
be done by calling {\tt plschr} with {\tt def=0.0} and {\tt scale} set to the
desired multiple of the default height. If the default height is to be
changed, {\tt def} is set to the new default height in millimetres, and
the new character height is again set to {\tt def} multiplied by {\tt
scale}.

The routine \rou{plssym} sets up the size of all subsequent symbols
drawn by calls to {\tt plpoin} and {\tt plsym}. It operates analogously
to {\tt plschr} as described above.

The lengths of major and minor ticks on the axes are set up by the routines
\rou{plsmaj} and \rou{plsmin}.

\section {Escape sequences in text} \label{escape}

The routines which draw text all allow you to include escape
sequeces in the text to be plotted. These are character sequences
which are are interpreted as instructions to
change font, draw superscripts and subscripts, draw non-ASCII
(e.g., Greek letters) etc. All escape sequences start with a double
backslash character (\verb+\\+).

The following escape sequences are defined:
\begin{itemize}
   \item \verb+\\u+: move up to the superscript position 
    (ended with \verb+\d+)
   \item \verb+\\d+: move down to subscript position 
    (ended with \verb+\\u+)
   \item \verb+\\b+: backspace (to allow overprinting)
   \item \verb+\\\\+: backslash
   \item \verb.\\+.: toggle overline mode
   \item \verb.\\-.: toggle underline mode
   \item \verb+\\gx+: Greek letter corresponding to Roman letter {\tt x} 
                     (see below)
   \item \verb+\\fn+: switch to normal font
   \item \verb+\\fr+: switch to Roman font
   \item \verb+\\fi+: switch to italic font
   \item \verb+\\fs+: switch to script font
   \item \verb+\\(nnn)+: Hershey character nnn (1 to 4 decimal digits)
\end{itemize}

Sections of text can have an underline or overline appended. For example,
the string
\[
{\rm\overline{S}(\underline{freq})}
\]
is obtained by specifying \verb."\\+S\\+(\\-freq\\-)"..

Greek letters are obtained by \verb+\\g+ followed by a Roman letter. 
Table~\ref{greek} shows how these letters map into Greek characters.
\begin{table}
   \centering
   \begin{tabular}{|l|*{12}{c|}}
   \hline
   Roman&A&B&G&D&E&Z&Y&H&I&K&L&M\\
   \hline
   Greek&A & B & $\Gamma$ & $\Delta$ & E & Z & H & $\Theta$ & I & K &
   $\Lambda$ & M \\
   \hline\hline
   Roman&N&C&O&P&R&S&T&U&F&X&Q&W\\
   \hline
   Greek&N & $\Xi$ & O & $\Pi$ & P & $\Sigma$ &
   T & $\Upsilon$ & $\Phi$ & X & $\Psi$ & $\Omega$ \\
   \hline\hline
   Roman&a&b&g&d&e&z&y&h&i&k&l&m\\
   \hline
   Greek&   $\alpha$ & $\beta$ & $\gamma$ & $\delta$ & $\epsilon$ & $\zeta$ & 
   $\eta$ & $\theta$ & $\iota$ & $\kappa$ &
   $\lambda$ & $\mu$ \\
   \hline\hline
   Roman&n&c&o&p&r&s&t&u&f&x&q&w\\
   \hline
   Greek& $\nu$ & $\xi$ & o & $\pi$ & $\rho$ & $\sigma$ &
   $\tau$ & $\upsilon$ & $\phi$ & $\chi$ & $\psi$ & $\omega$ \\
   \hline
   \end{tabular}
\caption{Roman characters corresponding to Greek characters}
\label{greek}
\end{table}

\section {Three dimensional surface plots} \label{threed}

PLPLOT includes routines that will represent a single-valued function
of two variables as a surface. In this section, we shall assume that
the function to be plotted is {\tt Z[X][Y]}, where {\tt Z} represents
the dependent variable and {\tt X} and {\tt Y} represent the independent 
variables.

As usual, we would like to refer to a three dimensional point {\tt (X,Y,Z)}
in terms of some meaningful user-specified coordinate system. These are
called {\em three-dimensional world coordinates}. We need to specify the
ranges of these coordinates, so that the entire surface is contained within the
cuboid defined by ${\tt xmin}<{\tt x}<{\tt xmax}$,
${\tt ymin}<{\tt y}<{\tt ymax}$ and
${\tt zmin}<{\tt z}<{\tt zmax}$. Typically, we shall want to view the
surface from a variety of angles, and to facilitate this, a two-stage
mapping of the enclosing cuboid is performed. Firstly, it is mapped
into another cuboid called the {\em normalized box} whose size must also
be specified by the user, and secondly this normalized box is viewed from
a particular azimuth and elevation so that it can be projected onto the
two-dimensional window.

This two-stage transformation process allows considerable flexibility in
specifying how the surface is depicted. The lengths of the sides of the
normalized box are independent of the world coordinate ranges of each of the
variables, making it possible to use ``reasonable'' viewing angles even if the
ranges of the world coordinates on the axes are very different. The size of the
normalized box is determined essentially by the size of the two-dimensional
window into which it is to be mapped. The normalized box is centred about the
origin in the $x$ and $y$ directions, but rests on the plane ${\tt z=0}$. It is
viewed by an observer located at altitude {\tt alt} and azimuth {\tt az}, where
both angles are measured in degrees. The altitude should be restricted to the
range zero to ninety degrees for proper operation, and represents the viewing
angle above the xy plane. The azimuth is defined so that when {\tt az=0}, the
observer sees the xz plane face on, and as the angle is increased, the observer
moves clockwise around the box as viewed from above the xy plane. The azimuth
can take on any value. 

The first step in drawing a surface plot is to decide on the size of the
two-dimensional window and the normalized box. For example, we could choose
the normalized box to have sides of length
\begin{verbatim}
basex=2.0;
basey=4.0;
height=3.0;
\end{verbatim}
A reasonable range for the $x$ coordinate of the two-dimensional
window is -2.5 to +2.5, since the length of the diagonal across the base of 
the normalized box is $\sqrt{2^2+4^2} = 2\sqrt{5}$, which fits into this 
coordinate range. A reasonable range for the $y$ coordinate of the two
dimensional window in this case is -2.5 to +4, as the the projection of the
normalized box lies in this range for the allowed range of viewing angles.

The routine \rou{plwind} or \rou{plenv} is used in the usual way
to establish the size of the two-dimensional window. The routine
\rou{plw3d} must then be called to establish the range of the three
dimensional world coordinates, the size of the normalized box and the
viewing angles. After calling {\tt plw3d}, the actual surface is
drawn by a call to \rou{plot3d}.

For example, if the three-dimensional world-coordinate ranges are
$-10.0\le{\tt x}\le 10.0$, $-3.0\le{\tt y}\le +7.0$ and
$0.0\le{\tt z}\le 8.0$, we could use the following statements:
\begin{verbatim}
      xmin2d = -2.5;                                                    
      xmax2d =  2.5;                                                   
      ymin2d = -2.5;                                                    
      ymax2d =  4.0;                                                    
      plenv(xmin2d,xmax2d,ymin2d,ymax2d);
      basex = 2.0;                               
      basey = 4.0;                                                      
      height = 3.0;                                                     
      xmin = -10.0;                                                     
      xmax = 10.0;                                                     
      ymin = -3.0;                                                      
      ymax = 7.0;                                                      
      zmin = 0.0;                                                       
      zmax = 8.0;                                                       
      alt = 45.0;                                                       
      az = 30.0;                                                       
      plw3d(basex,basey,height,xmin,xmax,ymin,ymax,zmin,zmax,alt,az);
      plot3d(x,y,z,work,ly,nx,ny,opt);
\end{verbatim}

The values of the function are stored in a two-dimensional
array {\tt z[][ly]} where the array element {\tt z[i][j]} contains the value
of the function at the point $x_i$, $y_j$. Note that the values of
the independent variables $x_i$ and $y_j$ do not need to be equally spaced,
but they must lie on a rectangular grid. Thus two further arrays {\tt x[nx]}
and {\tt y[ny]} are required as arguments to {\tt plot3d} to specify the
values of the independent variables. The values in the arrays x and y must 
be strictly increasing with the index. The argument {\tt opt} specifies
how the surface is outlined. If {\tt opt=1}, a line is drawn representing
z as a function of x for each value of y, if {\tt opt=2}, a line is drawn
representing z as a function of y for each value of x, and if {\tt opt=3},
a net of lines is drawn. The first two options may be preferable if one of
the independent variables is to be regarded as a parameter, whilst the third
is better for getting an overall picture of the surface. The final parameter
{\tt work} is an integer array with at least four times {\tt max(nx,ny)}
points, which is required for workspace.

Labelling a three-dimensional plot is somewhat more complicated than a two
dimensional plot due to the need for skewing the characters in the label
so that they are parallel to the coordinate axes. The routine \rou{plbox3}
thus combines the functions of box drawing and labelling. Its parameters
are described more fully in Chapter \ref{reference}.

The routine \rou{plside3} can be used to draw sides on three-dimensional
plots to give them a more solid look.  Grid lines perpendicular to the
z axis can be drawn with the routine \rou{plgrid3}.
Both routines are decribed in Chapter~\ref{reference}.

\section {Contour Plots}\label{contour}

A routine is available in PLPLOT which performs a contour plot of data 
stored in a two-dimensional array. A contour following algorithm is
used, so that it is possible to use non-continuous line styles.

The routine \rou{plcont} has the form
\name{plcont(z,nx,ny,kx,lx,ky,ly,clevel,nlevel,tr)}
where {\tt z} is the two-dimensional array of size ${\tt nx}\times{\tt ny}$
containing samples of the function to be contoured. The parameters
{\tt kx}, {\tt lx}, {\tt ky} and {\tt ly} specify the portion of {\tt z}
that is to be considered. The array {\tt clevel} of length {\tt nlevel}
is a list of the desired contour levels.

The path of each contour is initially computed in terms of the values of the
array indicies which range from 1 to {\tt nx} in the first index and from
1 to {\tt ny} in the second index. Before these can be drawn in the current
window (see page \pageref{window} in Section \ref{window}), it is necessary to
convert from these array indicies into world coordinates. This is done by
passing a pointer to a user-defined function to {\tt plcont}.  This
function pointer is the last argument {\tt tr}.
This function must be declared as type {\tt void} in the
module which calls {\tt plcont}. This transformation function
must have the parameter list
\name{void tr(x,y,tx,ty);}
where {\tt (x,y)}
is the point through which the contour runs expressed in
terms of array indicies, and {\tt (tx,ty)} are pointers to float variables
which are the world coordinates of
the point which corresponds to these indicies.

Often, the transformation between array indicies and world coordinates can
be expressed as a linear transformation. A routine is provided within the
library which can be passed to {\tt plcont} as the parameter {\tt tr}. This
transformation routine is as follows:
\begin{verbatim}

#include "plplot.h"

void xform(x,y,tx,ty)
float x, y, *tx, *ty;
{
      extern float tr[];

      *tx = tr[0]*x + tr[1]*y + tr[2];
      *ty = tr[3]*x + tr[4]*y + tr[5];
}
\end{verbatim}
Thus by setting up the values in the array {\tt tr[]}, we can
apply an arbitrary translation, rotation and/or shear to the array before
drawing out the contours. By defining other transformation subroutines,
it is possible to draw contours wrapped around polar grids etc.

As an example in setting up {\tt tr[]}, suppose that the array {\tt z} 
is of size $21 \times 41$ and contains the values of the function 
$z[x][y]$,
where $x$ ranges from 0.0 to 4.0 and $y$ ranges from -8.0 to 8.0. 
Furthermore,
let us also suppose that the window (as defined using {\tt plenv} or
{\tt plwind}) covers this range of world coordinates. 
Since we wish the index
(1,1) in array {\tt z} to map to (0.0,-8.0) and the index (21,41) to map
to (4.0,8.0), and for there to be no skew in the axes, we should choose
elements of {\tt tr[]} so that
\[
   \begin{array}{l@{\;=\;}l}
   tx & 0.2x - 0.2 \\
   ty & 0.4y - 8.4
   \end{array}
\]
and so {\tt tr[0]=0.2}, {\tt tr[1]=0.0}, {\tt tr[2]=-0.2},
{\tt tr[3]=0.0}, {\tt tr[4]=0.4}, {\tt tr[5]=-8.4}.

