\chapter{Graphics}
\label{chap:graphics} 

R has a very rich set of graphics facilities. The R home page,
\emph{http://www.r-project.org/}, has a few colorful examples, but to
really appreciate R's graphical power, browse through the R Graph
Gallery, \emph{http://addictedtor.free.fr/graphiques}.  

Our coverage here is not extensive at all, but it will give the reader
enough foundation to work the basics and learn more.  We will cover only
the bare minimum, on R's {\it base} or {\it traditional} graphics
package.  Readers interested in pursuing R graphics further are referred
to the excellent books on the subject, including (alphabetically) {\it
ggplot2:  Elegant Graphics for Data Analysis}, Hadley Wickham,
Springer-Verlag, 2009; {\it  Interactive and Dynamic Graphics for Data
Analysis: With R and GGobi} Dianne Cook, Deborah F. Swayne, A. Buja, and
D. Temple Lang, Springer-Verlag, 2007; {\it Lattice: Multivariate Data
Visualization with R}.  Deepayan Sarkar, Springer-Verlag, 2008; 
{\it R Graphics}, Paul Murrell, Chapman and Hall, 2005; and so on.  

\section{The Workhorse of R Base Graphics, the plot() Function}

This {\tt plot()} function forms the foundation for much of R's base
graphing operations, serving as the vehicle for producing many different
kinds of graphs. 

As mentioned in Section \ref{genericftns}, {\tt plot()} is a generic
function, or a placeholder for a family of functions.  The function
that actually gets called will depend on the class of the object on
which it is called.  Let's see what happens for example when we call
{\tt plot()} with an X vector and a Y vector, which are interpreted as a
set of pairs in the (X,Y) plane.   The call

\begin{Code}
> plot(c(1,2,3), c(1,2,4))
\end{Code}

\noindent
will cause a window to pop up, seen here in Figure \ref{figa}, plotting
the points (1,1), (2,2) and (3,4).  

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=3.0in]{Images/figa.png}
   }
   \caption{Simple point plot}
   \label{figa}
\end{figure}

This is a very plain Jane graph, of course.  We'll discuss some of the
fancy bells and whistles later.

The points in the graph will be symbolized by empty circles.  If you
want a different character type, specify a value for the named argument
{\tt pch} (``point character'').  

As noted in Section \ref{building}, one typically builds a graph through
a succession of several commands.  So, as a base, we might first draw an
empty graph, with only axes.  For instance,

\begin{Code}
> plot(c(-3,3), c(-1,5), type = "n", xlab="x", ylab="y")
\end{Code}

\noindent
draws axes labeled ``x'' and ``y'', the horizontal one
ranging from x = -3 to x = 3, and the vertical one ranging from y = -1
to y = 5.  The argument {\tt type="n"} means that there is nothing in
the graph itself.

%
% Below: seems like this should be a subhead under the plot() head,
% right? /kf
%

% NM:  Either way is fine.

\subsection{Plotting Multiple Curves on the Same Graph}
\label{building}

The {\tt plot()} function works in stages, which means you can build up
a graph in stages by issuing more and more commands, each of which adds
to the graph.  For instance, consider the following: 

\begin{Code}
> x <- c(1,2,3)
> y <- c(1,3,8)
> plot(x,y)
> lmout <- lm(y ~ x)
> abline(lmout)
\end{Code}

\noindent
The call to {\tt plot()} will graph the three points as in our example
above.  At this point the graph will simply show the three points, along
with the X and Y axes with hash marks.

The call to {\tt abline()} then adds a line to the current graph.  Now,
which line is this?  As we know from Section \ref{introregress}, the result
of the call to the linear regression function {\tt lm()} is a class
instance containing the slope and intercept of the fitted line, as well
as various other quantities that won't concern us here.  We've assigned
that class instance to {\tt lmout}.  The slope and intercept will now be
in {\tt lmout\$coefficients}.

Now, what happens when we call {\tt abline()}?  This is simply a
function that draws a straight line, with the function's arguments being
treated as the intercept and slope of the line.  For instance, the call
{\tt abline(c(2,1))} would draw the line

$$
y = 1 \cdot x + 2
$$

\noindent
on whatever graph we've built up so far.

But {\tt abline()} is written to take special action if it is called on
a regression object (though, surprisingly, it is not a generic
function).  Thus it will pick up the slope and intercept it needs from
{\tt lmout\$coefficients}, and it plots that line.  Note again that it
superimposes this line onto the current graph---the one which currently
graphs the three points.  In other words, the new graph will show both
the points and the line, as seen in Figure \ref{figb}.

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=3.0in]{Images/figb.png}
   }
   \caption{Using abline()}
   \label{figb}
\end{figure}

%
% Above figure should have a caption to match the others in the chapter.
% /kf
%

% NM:  A caption comes with the LaTeX "figure" environment.  But then
% it's floating, i.e. we have no control over where LaTeX will place the
% picture relative to the text.  Elsewhere here you correctly complain
% that the figures aren't close enough to their references in the text,
% which I agree with.  Since apparently the figure numbering disappears
% too without the "figure" environment, I've added it throughout the
% chapter.  There are a few tricks one can try to move the item closer
% to the intended text, but this is a tough problem, I've found.  Maybe
% others are more adept at it than I.

%
% Below: this seems like a subhead as well. /kf
%

% NM:  Again, I'd be happy either way.

\subsection{Starting a New Graph While Keeping the Old Ones}

Each time you call {\tt plot()} (directly or indirectly), the current
graph window will be replaced by the new one.  If you don't want that to
happen, you can on Linux systems call {\tt X11()}.  On a Mac, call {\tt
macintosh()}, and for Windows call {\tt windows()}.

Say for instance you wish to plot two histograms, of vectors {\tt x} and
{\tt y} and view them side by side.  On a Linux system, you'd type

\begin{Code}
> hist(x)
> x11()
> hist(y)
\end{Code}

%
% Worth showing a brief example here? Even if it's only you calling
% plot() then X11() then plot() again, or however it works. Would be
% good to clarify. /kf
%

% NM:  Added code.

\section{The lines() Function}

Though there are many options, the two basic arguments to {\tt lines()} are a
vector of X values and a vector of Y values. These are interpreted as (X,Y)
pairs representing points to be added to the current graph, with lines
connecting the points.

For instance, if x and y are the vectors (1.5,2.5) and (3,3), then the call

\begin{Code}
> lines(c(1.5,2.5),c(3,3))
\end{Code}

\noindent
would add a line from (1.5,3) to (2.5,3) to the present graph.

If  you  want  the lines ``connecting the dots" but don't want the dots
themselves, include {\tt type="l"} in your call to {\tt lines()}, or to
{\tt plot()}:

\begin{Code}
> plot(x,y,type="l")
\end{Code}

You can use the {\tt lty} parameter in {\tt plot()} to specify the type
of line, e.g solid, dashed, etc. Type

\begin{Code}
> help(par)
\end{Code}

to see the various types and their codes.

\section{Extended Example:  Two Density Estimates on the Same Graph}
\label{2dens}

Let's plot nonparametric density estimates (these are basically smoothed
histograms) for two sets of examination scores in the same graph. We use
the function {\tt density()} to generate the estimates. Here are the
commands we issue:

\begin{Code}
> d1 = density(testscores$Exam1,from=0,to=100)
> d2 = density(testscores$Exam2,from=0,to=100)
> plot(d1,main="",xlab="")
> lines(d2)
\end{Code}

% NM (DO NOT REMOVE THIS COMMENT):  This was my file
% ExamScores158S08.txt.

First, we computed nonparametric density estimates from the two
variables, saving them in objects {\tt d1} and {\tt d2} for later use.
We then called {\tt plot()} to draw the curve for Exam 1, at which point
the plot looked like Figure \ref{figd}.  We then called {\tt lines()} to
add Exam 2's curve to the graph, producing Figure \ref{fige}

%
% These figure references both seem to be generating the name "Figure
% 11.4," at least for me. The figure captions also don't seem to be
% displaying. /kf
%

% NM:  OK now, right?

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/figd.png}
   }
   \caption{Plot first density}
   \label{figd}
\end{figure}

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/fige.png}
   }
   \caption{Add second density}
   \label{fige}
\end{figure}

Note that we asked R to have blank labels for the figure as a whole and
for the X axis.  Otherwise, R would have gotten such labels from {\tt
d1}, which would have been specific to Exam 1.  

Note too that we had to plot Exam 1 first.  The scores there were less
diverse, so the density estimate was narrower and taller.  Had we
plotted Exam 2 first, with its shorter curve, Exam 1's curve would then
have been too tall for the plot window.  

Here, we ran the two plots separately to see which was taller, but
consider a more general situation.  Say we wish to write a
broadly-usable function that will plot several density estimates on the
same graph.  Then we'd need to automate the process of determining which
density estimate is tallest.  To do so, we would use the fact that the
estimated density values are contained in the {\tt y} component of the
return value from the call to \lstinline{density()}.  We would call
\lstinline{max()} on each density estimate, then use
\lstinline{which.max()} to determine which density estimate is the
tallest.

The  call to {\tt plot()} both initiates the plot and draws the first curve.
(Without specifying type="l", only the points would have been plotted.) The
call to {\tt lines()} then adds the second curve.

\section{Extended Example: More on the Polynomial Regression Example}
\label{plotpoly}

In Section \ref{polyregression}, we defined a class {\tt polyreg} that
facilitates fitting of polynomial regression models.  Our code there
included an implementation of the generic {\tt print()} function.  Let's 
now add one for the generic {\tt plot()}:

% \begin{Code2}[numbers=left]
\begin{lstlisting}[numbers=left]
# polyfit(x,maxdeg) fits all polynomials up to degree maxdeg; y is
# vector for response variable, x for predictor; creates an object of
# class "polyreg", consisting of outputs from the various regression
# models, plus the original data
polyfit <- function(y,x,maxdeg) {
   pwrs <- powers(x,maxdeg)  # form powers of predictor variable
   lmout <- list()  # start to build class
   class(lmout) <- "polyreg"  # create a new class
   for (i in 1:maxdeg) {
      lmo <- lm(y ~ pwrs[,1:i])
      # extend the lm class here, with the cross-validated predictions
      lmo$fitted.xvvalues <- lvoneout(y,pwrs[,1:i,drop=F])
      lmout[[i]] <- lmo
   }
   lmout$x <- x
   lmout$y <- y
   return(lmout)
}

# generic print() for an object fits of class "polyreg":  print
# cross-validated mean-squared prediction errors
print.polyreg <- function(fits) {
   maxdeg <- length(fits) - 2  # count lm() outputs only, not $x and $y
   n <- length(fits$y)
   tbl <- matrix(nrow=maxdeg,ncol=1)
   cat("mean squared prediction errors, by degree\n")
   colnames(tbl) <- "MSPE"
   for (i in 1:maxdeg) {
      fi <- fits[[i]]
      errs <- fits$y - fi$fitted.xvvalues
      spe <- sum(errs^2)  
      tbl[i,1] <- spe/n
   }
   print(tbl)
}

# generic plot(); plots fits against raw data
plot.polyreg <- function(fits) {
   plot(fits$x,fits$y,xlab="X",ylab="Y")  # plot data points as background
   maxdg <- length(fits) - 2
   cols <- c("red","green","blue")
   dg <- curvecount <- 1
   while (dg < maxdg) {
      prompt <- paste("RETURN for XV fit for degree",dg,"or type degree",
         "or q for quit ")
      rl <- readline(prompt)
      dg <- if (rl == "") dg else if (rl != "q") as.integer(rl) else break
      lines(fits$x,fits[[dg]]$fitted.values,col=cols[curvecount%%3 + 1])
      dg <- dg + 1
      curvecount <- curvecount + 1
   }
}

# forms matrix of powers of the vector x, through degree dg
powers <- function(x,dg) {
   pw <- matrix(x,nrow=length(x))
   prod <- x
   for (i in 2:dg) {
      prod <- prod * x
      pw <- cbind(pw,prod)
   }
   return(pw)
}

# finds cross-validated predicted values; could be made much faster via
# matrix-update methods
lvoneout <- function(y,xmat) {
   n <- length(y)
   predy <- vector(length=n)
   for (i in 1:n) {
      # regress, leaving out i-th observation
      lmo <- lm(y[-i] ~ xmat[-i,])
      betahat <- as.vector(lmo$coef)
      # the 1 accommodates the constant term
      predy[i] <- betahat %*% c(1,xmat[i,])
   }
   return(predy)
}

# polynomial function of x, coefficients cfs
poly <- function(x,cfs) {
   val <- cfs[1]
   prod <- 1
   dg <- length(cfs) - 1
   for (i in 1:dg) {
      prod <- prod * x
      val <- val + cfs[i+1] * prod
   }
}
\end{lstlisting}
% \end{Code2}

As noted, the only new code is \lstinline{plot.polyreg()}.  For
convenience, the code is reproduced here:

\begin{Code}
# generic plot(); plots fits against raw data
plot.polyreg <- function(fits) {
   plot(fits$x,fits$y,xlab="X",ylab="Y")  # plot data points as background
   maxdg <- length(fits) - 2
   cols <- c("red","green","blue")
   dg <- curvecount <- 1
   while (dg < maxdg) {
      prompt <- paste("RETURN for XV fit for degree",dg,"or type degree",
         "or q for quit ")
      rl <- readline(prompt)
      dg <- if (rl == "") dg else if (rl != "q") as.integer(rl) else break
      lines(fits$x,fits[[dg]]$fitted.values,col=cols[curvecount%%3 + 1])
      dg <- dg + 1
      curvecount <- curvecount + 1
   }
}
\end{Code}

As before, our implementation of the generic function takes the name of
the class, here {\tt plot.polyreg()}.

The {\tt while} loop goes through the various polynomial degrees.  We
cycle through three colors, via setting the vector {\tt cols}; note the
expression \lstinline{curvecount %% 3} for this purpose.

The user is given a choice as to whether to plot the next sequential
degree, or a different one selected by the user.  The query, both user prompt
and reading of the user's reply, is done in the line

\begin{Code}
rl <- readline(prompt)
\end{Code}

%
% The above code could really use some more explanation. /kf
%

% NM:  Done.

We use the R string function {\tt paste()} to assemble a prompt,
offering the user a choice of plotting the next fitted polynomial, or
one of a different degree, or quitting.  The prompt appears in the
interactive R window in which we issued the {\tt plot()} call.  So for
instance after taking the default choice twice, the command window looks
like this

\begin{Code}
> plot(lmo)
RETURN for XV fit for degree 1 or type degree or q for quit 
RETURN for XV fit for degree 2 or type degree or q for quit 
RETURN for XV fit for degree 3 or type degree or q for quit 
\end{Code}

\noindent
while the plot window looks like Figure \ref{figc}.

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=3.0in]{Images/figc.png}
   }
   \caption{Plotting polynomial fit}
   \label{figc}
\end{figure}

\section{Adding Points}

The {\tt points()} function adds a set of (x,y)-points, with labels for
each, to the currently displayed graph.  For instance, in our first
example, Section \ref{first}, the command

\begin{Code}
points(testscores$Exam1,testscores$Exam3,pch="+")
\end{Code}

\noindent
would superimpose onto the current graph the points of the exam scores from
that example, using "+" signs to mark them.

As with most of the other graphics functions, there are lots of options,
such as point color and background color.  As before, type  

\begin{Code}
> help(par)
\end{Code}

\noindent 
to explore the myriad of options.  For instance, typing

\begin{Code}
> par(bg="yellow")
\end{Code}

\noindent 
will result in your graphs having yellow background from now on, until
you specify otherwise.

%
% Above: How can they set these options? What about some examples? /kf
%

% NM:  It's endless.  I've added a quick example.

\section{The legend() Function}

A nice function is {\tt legend()}, which is used to add a legend to a
multicurve graph.  This could tell the viewer something like, ``The
green curve is for the men, while the red curve displays the data for
the women.'' Type

\begin{Code}
> example(legend)
\end{Code}

\noindent
to see some very nice examples.

%
% Above: why not show an image of this? I don't really get what this
% does from the text alone... /kf
%

% NM:  You're right.  But I've now referred the reader to R's own examples,
% which would be prettier than mine.

\section{Adding Text: the text() Function}

Use the {\tt text()} function to place some text anywhere in the current graph.
For example,

\begin{Code}
text(2.5,4,"abc")
\end{Code}

\noindent
would write the text "abc" at the point (2.5,4) in the graph. The center of
the string, in this case "b", would go at that point.

To see a more practical example, let's add some labels to the curves in
Section \ref{2dens} (assuming the plot is our current one, so we can add
to it):

\begin{Code}
> text(46.7,0.02,"Exam 1")
> text(12.3,0.008,"Exam 2")
\end{Code}

\noindent
The result is shown in Figure \ref{figf}.


\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/figf.png}
   }
   \caption{Placing text}
   \label{figf}
\end{figure}



In order to get a certain string placed exactly where you want it, you
may need to engage in some trial and error. But you may find the {\tt
locator()} function, which we'll discuss in the next section, to be a
much quicker way to go.

%
% Above: what does the locator() function have to do with undoing? /kf
%

% NM:  Yes, it was confusing.  Deleted.

% To add text in the margins, use {\tt mtext()}.

%
% Above: an example of this? /kf
%

% NM:  I'm not sure why I included this.  Even R's own examples are
% poor.  Deleted.

\section{Pinpointing Locations: the locator() Function}
\label{locator}

As noted earlier, placing text in a graph, in exactly the place you
wish, can be tricky.  You could use trial and error, repeatedly trying 
different X- and Y-coordinates until you find a good position.  But the
{\tt locator()} function can save you a lot of trouble.  You simply call
the function, then click the mouse at exactly the desired spot in the
graph, and the function returns the X- and Y-coordinates of your click
point.

%
% I'd pull the explanation of what the function does up here, above the
% code, then show the examples. I'm also not entirely sure what this is
% doing. Will this appear in the graph window, in the term, in a dialog,
% or what? /kf
%

% NM:  Wording expanded.

Specifically, typing

\begin{Code}
locator(1)
\end{Code}

\noindent
will tell R that you will click in 1 place in the graph. Once you do so, R
will  tell you the exact coordinates of the point you clicked on. Call
\lstinline{locator(2)} to get the locations of two places, and so on.  
(Warning:  Make sure to include the argument.)

Here is a small example:

\begin{Code}
> hist(c(12,5,13,25,16))
> locator(1)
$x
[1] 6.239237

$y
[1] 1.221038
\end{Code}

\noindent 
I had R draw a histogram, and then I called \lstinline{locator()} with
the argument 1, indicating I would then click the mouse once.  I did so,
and the function returned a list with components {\tt x} and {\tt y},
the X- and Y-coordinates of the point at which I clicked.

%
% Above: you mean not to call locator()? What happens? /kf
%

% NM:  What do you mean?

You can combine this, for example, with {\tt text()}, e.g.

%
% What does this do? /kf
%

\begin{Code}
> text(locator(1),"nv=75")
\end{Code}

\noindent 
Here, \lstinline{text()} was expecting an X- and Y-coordinate,
specifying the point at which to draw the text "nv=75".  The return
value of \lstinline{locator()} supplied those coordinates.

\section{Replaying a Plot}
\label{replay}

R has no ``undo'' command.  However, if you suspect you may need to undo
your next step of a graph, you can save it using {\tt recordPlot()}, and
then later restore it with {\tt replayPlot()}.  

Less formally but more conveniently, you can put all the commands you're
using to build up a graph in a file, and then use {\tt source()}, or
cut-and-paste with the mouse, to execute them.  If you change one
command, you can then redo the whole graph by sourcing or
copying-and-pasting your file.

In the example in Section \ref{2dens}, for instance, we could create
file named {\tt examplot.r}, with the following contents:

\begin{Code}
d1 = density(testscores$Exam1,from=0,to=100)
d2 = density(testscores$Exam2,from=0,to=100)
plot(d1,main="",xlab="")
lines(d2)
text(46.7,0.02,"Exam 1")
text(12.3,0.008,"Exam 2")
\end{Code}

\noindent
If we decided that the label for Exam 1 was a bit far to the right, we
can edit the file, and then either execute

\begin{Code}
> source("examplot")
\end{Code}

\noindent
or do the copy-and-paste.

\section{Changing Character Sizes: the cex Option}
\label{cex}

The {\tt cex} ("character expand") function allows you to expand or
shrink characters within a graph, which can be very useful. You can use
it as a named parameter in various graphing functions. For example,

%
% Above: what are some cases where it would be useful? /kf
%

% NM:  Added comment.

For instance, you may wish to draw the text "abc" at some point, say
(2.5,4) in your graph, but with a larger font, in order to call
attention to this particular text.  You could do this by typing

\begin{Code}
text(2.5,4,"abc",cex = 1.5)
\end{Code}

\noindent
would print the same text as in our earlier example, but with characters 1.5
times normal size.

\section{Operations on Axes}

You may wish to have the ranges on the X- and Y-axes of your plot be
broader or narrower than the default. You can do this by specifying the
{\tt xlim} and/or {\tt ylim} parameters in your call to {\tt plot()} or
{\tt points()}. For example, {\tt ylim=c(0,90000)} would specify a range
on the Y-axis of 0 to 90000.

%
% How about an example and image? /kf
%

% NM:  Added.

This is especially useful if you will be displaying several curves in
the same graph. Note that if you do not specify {\tt xlim} and/or {\tt
ylim}, you should draw the tallest curve first so there is room for all
of them; otherwise, R will fit the plot to the first one your draw, then
cut off taller ones at the top!  We took this approach, for example,
when we plotted two density estimates on the same graph in Section
\ref{2dens}, Figures \ref{figd} and \ref{fige}.

What we could have done instead is first found the highest values of the
two density estimates.  For {\tt d1}, for example:

\begin{Code}
> d1

Call:
	density.default(x = testscores$Exam1, from = 0, to = 100)

Data: testscores$Exam1 (39 obs.);	Bandwidth 'bw' = 6.967

       x             y            
 Min.   :  0   Min.   :1.423e-07  
 1st Qu.: 25   1st Qu.:1.629e-03  
 Median : 50   Median :9.442e-03  
 Mean   : 50   Mean   :9.844e-03  
 3rd Qu.: 75   3rd Qu.:1.756e-02  
 Max.   :100   Max.   :2.156e-02  
\end{Code}

\noindent 
So, the largest Y value was .022.  For {\tt d2} it was only 0.017.  So
we should have plenty of room if we set {\tt ylim} at, say 0.03.  Here
is how we could draw the two plots on the same picture:

\begin{Code}
> plot(c(0, 100), c(0, 0.03), type = "n", xlab="score", ylab="density")
> lines(d2)
> lines(d1)
\end{Code}

First we drew the bare-bones plot, just axes, no innards; see Figure
\ref{figpred2d1}.  The first two arguments to \lstinline{plot()}
give {\tt xlim} and {\tt ylim}, so that the lower and upper limits on
the Y axis will be 0 and 0.03.  Calling \lstinline{lines()} twice then
fills in the graph, yielding Figures \ref{figd2} and
\ref{figd2d1}.  (Either of the two \lstinline{lines()} calls could
come first, as we've left enough room.)

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/figpred2d1.pdf}
   }
   \caption{Axes only}
   \label{figpred2d1}
\end{figure}

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/figd2.pdf}
   }
   \caption{Add d2}
   \label{figd2}
\end{figure}

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/figd2d1.pdf}
   }
   \caption{Add d1}
   \label{figd2d1}
\end{figure}

%
% Ambiguous sentence above -- I tried to rewrite, but please check for
% accuracy. /kf
%

% NM:  Your phrasing was OK, but I've expanded a bit.

\section{The polygon() Function}

%
% Below: what do you mean, "shading, etc." What's the etc? /kf
%

% NM:  Explained later.

You can use {\tt polygon()} to draw arbitrary polygonal objects. 
For example, the following code draws the graph of the
function $f(x) = 1 - e^{-x}$, then adds a rectangle that approximates
the area under the curve from x = 1.2 to x = 1.4:

\begin{Code}
> f <- function(x) return(1-exp(-x))
> curve(f,0,2)
> polygon(c(1.2,1.4,1.4,1.2),c(0,0,f(1.3),f(1.3)),col="gray")
\end{Code}

\noindent 
The result is shown in Figure \ref{figrectangle}.

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/figrectangle.pdf}
   }
   \caption{Rectangular area strip}
   \label{figrectangle}
\end{figure}

%
% Why not show an image of what this looks like? /kf
%

% NM:  Done.

In the call to {\tt polygon()} here, the first argument is the set of X
coordinates for the rectangle, while the second argument specifies the Y
coordinates.  The third argument specifies that the rectangle should be
shaded in solid gray.  Instead we could have, for instance, used the {\tt
density} argument to fill the rectangle with striping.  The call

\begin{Code}
> polygon(c(1.2,1.4,1.4,1.2),c(0,0,f(1.3),f(1.3)),density=10)
\end{Code}

\noindent 
would specify 10 lines per inch.

%
% Above: how could we have used the density argument for striping? /kf
%

% NM:  Fixed.

\section{Smoothing Points: the lowess() Function}

Just plotting a cloud of points, whether connected or not, may turn out
to be an uninformative mess. In many cases, it is better to smooth out
the data by fitting a nonparametric regression estimator such as {\tt
lowess()}.

Let's do that for the test score data we saw earlier, plotting the
scores of Exam 2 against those of Exam 1:

\begin{Code}
> plot(testscores)
> lines(lowess(testscores))
\end{Code}

The result is in Figure \ref{figlowess}.

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=4.0in]{Images/figlowess.pdf}
   }
   \caption{Smoothing the exam score relation}
   \label{figlowess}
\end{figure}


%
% This is another place where it would be really useful to actually have
% images to look at. I'd like to see the uninformative mess, then see
% the "smoothed" data to compare it with. As it stands, I have no idea
% what the lowess() function is actually doing. /kf
%

% NM:  Good point.  Added.

A newer alternative to \lstinline{lowess()} is \lstinline{loess()}.  The
two functions are quite similar, but with different defaults and so on.
One needs some advanced knowledge of statistics to appreciate the
differences; use whichever you find gives better smoothing.

%
% Above: "Different defaults and so on?" Can you be more explicit here?
% Again, examples would be good. /kf
%

% NM:  This gets quite technical.  I've added a comment to that effect.

\section{Graphing Explicit Functions}
\label{explicit}

Say you wanted to plot the function $g(t) = (t^2+1)^{0.5}$ for t between
0 and 5. You could use the following R code:

\begin{Code}
g <- function(t) { return (t^2+1)^0.5 }  # define g()
x <- seq(0,5,length=10000)  # x = [0.0004, 0.0008, 0.0012,..., 5]
y <- g(x)  # y = [g(0.0004), g(0.0008), g(0.0012), ..., g(5)]
plot(x,y,type="l")
\end{Code}

But you could avoid some work on your part here by using the {\tt
curve()} function, which basically uses the same method:

\begin{Code}
> curve((x^2+1)^0.5,0,5)
\end{Code}

If you were adding this curve to an existing plot, you would use the
{\tt add} argument:

\begin{Code}
> curve((x^2+1)^0.5,0,5,add=T)
\end{Code}

The optional argument {\tt n} has the default value 101, meaning that
the function will be evaluated at 101 equally-spaced points in the
specified range of X.

%
% Above: what happens when you change the value of n? Why might you want
% to do this? Is 101 generally a pretty good value? I think many of
% these explanations would benefit from more detail. /kf
%

% NM:  Comment added.

Use just enough points for visual smoothness.  If you find 101 is 
not enough, experiment with higher values of {\tt n}.

You can also use {\tt plot()}:

%
% Is there a particular benefit to doing it one way or the other? /kf
%

% NM:  Comment added below.

\begin{Code}
> f <- function(x) return((x^2+1)^0.5)
> plot(f,0,5)  # the argument must be a function name
\end{Code}

\noindent
Here the call {\tt plot()} leads to calling {\tt
plot.function()}, the implementation of generic 
{\tt plot()} function for the {\tt function} class.

Again, your choice.  Use whichever approach you find most convenient.

\section{Extended Example:  Magnifying a Portion of a Curve}
\label{magnify}

We can use {\tt curve()} to graph a function, as seen above.  However,
after graphing it, we may wish to ``zoom in'' on one portion of the
curve.  We could do this by simply calling {\tt curve()} again, on the
same function but with restricted X range, but suppose we wish to
display the original plot and the closeup one in the same picture.  Here
we will develop a function, to be named {\tt inset()}, to do this.

In order to avoid redoing the work that {\tt curve()} did in plotting
the original graph, we will slightly modify its code, to save its work,
via a return value.  We can do that by taking advantage of the fact that
one can easily inspect the code of R functions written in R (as opposed
to the fundamental R functions written in C):

\begin{Code2}[numbers=left]
> curve
function (expr, from = NULL, to = NULL, n = 101, add = FALSE, 
    type = "l", ylab = NULL, log = NULL, xlim = NULL, ...) 
{
    sexpr <- substitute(expr)
    if (is.name(sexpr)) {
# ...lots of lines omitted here...
    x <- if (lg != "" && "x" %in% strsplit(lg, NULL)[[1]]) {
        if (any(c(from, to) <= 0)) 
            stop("'from' and 'to' must be > 0 with log=\"x\"")
        exp(seq.int(log(from), log(to), length.out = n))
    }
    else seq.int(from, to, length.out = n)
    y <- eval(expr, envir = list(x = x), enclos = parent.frame())
    if (add) 
        lines(x, y, type = type, ...)
    else plot(x, y, type = type, ylab = ylab, xlim = xlim, log = lg, 
        ...)
}
\end{Code2}

The code forms vectors {\tt x} and {\tt y}, consisting of the X and Y
coordinates of the curve to be plotted, at {\tt n} equally-spaced points
in the range of X.  Since we'll make use of those in {\tt inset()},
let's modify the above code to return {\tt x} and {\tt y}, giving the
name {\tt crv()} to the modified {\tt curve()}:

\begin{Code2}[numbers=left]
> crv
function (expr, from = NULL, to = NULL, n = 101, add = FALSE, 
    type = "l", ylab = NULL, log = NULL, xlim = NULL, ...) 
{
    sexpr <- substitute(expr)
    if (is.name(sexpr)) {
# ...lots of lines omitted here...
    x <- if (lg != "" && "x" %in% strsplit(lg, NULL)[[1]]) {
        if (any(c(from, to) <= 0)) 
            stop("'from' and 'to' must be > 0 with log=\"x\"")
        exp(seq.int(log(from), log(to), length.out = n))
    }
    else seq.int(from, to, length.out = n)
    y <- eval(expr, envir = list(x = x), enclos = parent.frame())
    if (add) 
        lines(x, y, type = type, ...)
    else plot(x, y, type = type, ylab = ylab, xlim = xlim, log = lg, 
        ...)
    return(list(x=x,y=y))  # this is the only modification
}
\end{Code2}

So, here is our {\tt inset()} function:

\begin{Code2}[numbers=left]
# savexy:  list consisting of x and y vectors returned by crv()
# x1,y1,x2,y2:  coordinates of rectangular region to be magnified
# x3,y3,x4,y4:  coordinates of inset region 
inset <- function(savexy,x1,y1,x2,y2,x3,y3,x4,y4) {
   rect(x1,y1,x2,y2)  # draw rectangle around region to be magnified
   rect(x3,y3,x4,y4)  # draw rectangle around the inset
   # get vectors of coordinates of previously plotted points
   savex <- savexy$x
   savey <- savexy$y
   # get subscripts of xi our range to be magnified
   n <- length(savex)
   xvalsinrange <- which(savex >= x1 & savex <= x2)
   yvalsforthosex <- savey[xvalsinrange]
   # check that our first box contains the entire curve for that X range
   if (any(yvalsforthosex < y1 | yvalsforthosex > y2)) {
      print("Y value outside first box")
      return()
   }
   # record some differences
   x2mnsx1 <- x2 - x1
   x4mnsx3 <- x4 - x3
   y2mnsy1 <- y2 - y1
   y4mnsy3 <- y4 - y3
   # for the i-th point in the original curve, the function plotpt() will 
   # calculate the position of this point in the inset curve
   plotpt <- function(i) {
      newx <- x3 + ((savex[i] - x1)/x2mnsx1) * x4mnsx3 
      newy <- y3 + ((savey[i] - y1)/y2mnsy1) * y4mnsy3 
      return(c(newx,newy))
   }
   newxy <- sapply(xvalsinrange,plotpt)
   lines(newxy[1,],newxy[2,])
}
\end{Code2}

%
% Above: looks like the comments are getting eaten up by the Code2
% blocks here. /kf
%

% NM:  Looks fine to me.  Which commas?

Let's try it out:

\begin{Code}
png("inset.png")
xyout <- crv(exp(-x)*sin(1/(x-1.5)),0.1,4,n=5001)
inset(xyout,1.3,-0.3,1.47,0.3,  2.5,-0.3,4,-0.1)
dev.off()
\end{Code}

\noindent
The resulting plot looks like Figure \ref{inset}.

%
% It would be nice for these figures to appear a bit closer to their
% references, if possible. /kf
%

% NM:  See previous comment.

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=3.0in]{Images/inset.png}
   }
   \caption{Adding an inset graph}
   \label{inset}
\end{figure}

\section{Graphical Devices and Saving Graphs to Files}
\label{savegraph}

%
% Below: this seems like an awkward way to put this... R "has the
% notion" of a graphics device? Is there any way you can reword this to
% clarify? /kf
%

% NM:  Done.

R graphics display can be on various {\it graphics devices}. The default
device is the screen. If we want to have a graph saved to a file, we
must set up another device.  Let's go through the basics of R graphics
devices first, via which we will find one approach to switching graphics
devices, and then discuss a second approach.  The latter is much more
direct and convenient, but we go through the former as a means of
introducing R graphics devices concepts.

%
% Above: solution to what? Saving to a file? Setting up different
% devices? /kf
%

% NM:  Fixed.

%
% Also, is it "graphics device" or "graphical device?" Best to be
% consistent here. /kf
%

% NM:  I think I've always said "graphics device," which is what the R
% online help says.

Suppose we type

\begin{Code}
> pdf("d12.pdf")
\end{Code}

\noindent
This opens a file, which we have chosen here to call {\tt d12.pdf}. We now have
two devices open, as we can confirm:

\begin{Code}
> dev.list()
X11 pdf
  2   3
\end{Code}

%
% Below: what is the screen named when it's run on other OSes? /kf
%

% NM:  Fixed.

\noindent
The screen is named X11 when R runs on Linux (it's named ``windows'' on
Windows systems); it is device number 2 here.  Our PDF file is device 
number 3.  Our active device is now the PDF file: 

\begin{Code}
> dev.cur()
pdf 
  3 
\end{Code}

All graphics output will now go to this file instead of to the screen.
But what if we wish to save what's already on the screen?  One approach
(not necessarily the best, as will be discussed shortly) would be to
re-establish the screen as the current device, then copy it to the PDF
device, 3:

\begin{Code}
> dev.set(2)
X11
  2
> dev.copy(which=3)
pdf
  3
\end{Code}

%
% Below: seems a little strange to refer to yourself in the third person
% like this.
%
% Also, is this common knowledge? Do we need to "cite" him like this?
% The reader likely won't care who told you this, they just want to know
% the information. /kf
%

% NM:  He was listed at the beginning of the chapter as the famous
% author of an R graphics book.  But I'll just thank him in the preface.

\noindent
But actually, it is best to set up a PDF device as above, and then 
re-run whatever analyses led to the current screen, as the copy 
operation can result in distortions due to mismatches between screen 
devices and file devices.
  
Note carefully that the PDF file we create is not usable until we close
it, which we do as follows:

\begin{Code}
> dev.set(3)
pdf
  3
> dev.off()
X11
  2
\end{Code}

%
% Below: probably better? Why? Also, should you mention the
% output/return values that are shown after each of these function
% calls? /kf
%

% NM:  Fixed.

\noindent
We could also close the device by exiting R, if we're otherwise done.
But in future versions of R, this ``option'' may not exist, so 
it's probably better to proactively close.

%
% The below seems useful, why the cut? /kf
%

% NM:  Easier just to use pdf().  Earlier versions of R didn't have
% that, so I wrote the code below.  It's pretty much redundant now.

% The above set of operations to print a graph can become tedious if used a
% lot, so it makes sense to put them into a file, say {\tt prigra.r}, so
% as to avoid having to type them by hand all the time in the future:
% 
% \begin{Code}
% # prints the currently displayed graph, on device number dvnum, to the
% # file filename; dvnum will typically be 2; filename must be the name of
% # a PDF file, quoted; it closes the PDF file and restores dvnum as the
% # current device
% 
% prpdf <- function(dvnum, filename)  {
%    pdf(filename)  # output from now on will go to the specified PDF file
%    dvc <- dev.cur()  # determine our active display device
%    dev.set(dvnum)  # set active device to the specified one
%    dev.copy(which=dvc)  # copy
%    dev.set(dvc)
%    dev.off()
%    dev.set(dvnum)
% }
% \end{Code}

\section{3-Dimensional Plots}
\label{3d}

There are a number of functions to plot data in three dimensions, such
as {\tt persp()} and {\tt wireframe()}, which draw surfaces, and {\tt
cloud()}, which draws three dimensional scatter plots.  There are many
more, with elaborate options too specialized for this book.  Readers are
referred to the books cited at the beginning of this chapter, but let's
look at a simple case:

%
% Above: There are many more... and? Seems like an abrupt way to put
% this. Perhaps point them to a place where they can learn more, or
% maybe just reword? Or cut? /kf
%

For {\tt wireframe()} and {\tt cloud()}, one loads the {\tt lattice}
library.  Here is an example:

%
% Should you show the library being loaded in the example? /kf
%

% NM:  OK.

\begin{Code}
> library(lattice)
> a <- 1:10
> b <- 1:15
> eg <- expand.grid(x=a,y=b)
> eg$z <- eg$x^2 + eg$x * eg$y
> wireframe(z ~ x+y, eg)
\end{Code}

\noindent
The call to {\tt expand.grid()} creates a data frame, consisting of two
columns named {\tt x} and {\tt y}, in all possible combinations of 
the values of the two inputs.  Here {\tt a} and {\tt b} had 10 and 15 
values, respectively, so the resulting data frame will have 150 rows.  

We then added a third column, named {\tt z}, as a function of the first
two columns.  Our call to {\tt wireframe()} then creates the graph.  The
arguments, given in ``regression model'' form, specify in this case that
{\tt z} is to be graphed against {\tt x} and {\tt y}.  Of course, {\tt
z}, {\tt x} and {\tt y} refer to names of columns in {\tt eg}.

The result is shown in Figure \ref{figwireframe}.

\begin{figure}[tb]
   \centerline{
      \includegraphics[width=3.0in]{Images/figwireframe.pdf}
   }
   \caption{Example of wireframe()}
   \label{figwireframe}
\end{figure}

All the points are connected as a surface (like connecting points
by lines in two dimensions).  With {\tt cloud()}, though, the points
would just be isolated.

%
% Again, this seems like a logical place to show some images of the
% output of these functions rather than trying to describe them. /kf
%

% NM:  Done.

For {\tt wireframe()}, the (X,Y) pairs must form a rectangular grid,
though not necessarily evenly spaced.

Note that the data frame that is input to {\tt wireframe()} need not
have been created by {\tt expand.grid()}.  

By the way, these functions have many different options.  A nice one for
{\tt wireframe()}, for instance, is {\tt shade=T}, which makes it all
easier to see.

%
% How about showing a few more of these options? /kf
%

% NM:  These really do get complicated.  They require a good ability to
% visualize in 3 dimensions, and to be able to come up with the math
% needed for the picture.  As I mentioned at the outset of this chapter,
% I can only just scratch the surface of this huge graphics field.

