[R] mult.fig() utility [was "margin text mtext"]
Martin Maechler
maechler at stat.math.ethz.ch
Mon Jun 11 08:54:44 CEST 2001
>>>>> "Paul" == Paul Murrell <paul at stat.auckland.ac.nz> writes:
Paul> Hi
>> Fiddling around with "mar" and "mtext" I got stuck:
>>
>> plot.pcaX <- function(tit,lab) {
>> on.exit(par(oldpar <- par(oma=c(4, 2, 4, 2), mar = c(4, 4, 2, 1)))) # ??
>> split.screen(figs=c(3,3))
>> for (i in 1:9) {screen(i); plot(rnorm(100),rnorm(100)) }
>> mtext(tit, side = 3, line = 1, outer = TRUE, cex = 1.5, adj = 0.5)
>> mtext(paste(lab,", ", date()),side = 1,line=0,outer=TRUE,cex=0.5,adj=1)
>> close.screen(all=T)
>> }
>>
>> plot.pcaX("test","test.ps")
>>
>> The plots are arranged without any margins, and "test" and "test.ps" will
>> not be printed on the plot.
Paul> A couple of things ...
Paul> (i) the code within on.exit() is not executed until the function
Paul> exits which is why your margins are not affected during the
Paul> function call
Paul> (ii) you should probably be using par(mfrow) instead of screen()
Paul> et al A suggested modification of your function is:
Paul> plot.pcaX <- function(tit,lab) {
Paul> oldpar <- par(oma=c(4, 2, 4, 2), mar = c(4, 4, 2, 1)) # ??
Paul> on.exit(par(oldpar)) # ??
Paul> par(mfrow=c(3,3))
Paul> for (i in 1:9) { plot(rnorm(100),rnorm(100)) }
Paul> mtext(tit, side = 3, line = 1, outer = TRUE, cex = 1.5, adj = 0.5)
Paul> mtext(paste(lab,", ", date()),side = 1,line=0,outer=TRUE,cex=0.5,adj=1)
Paul> }
Paul> Hope that helps
Now that this is solved...
The task of setting up a multi-figure plot with a title
(and "fixing" mar a bit) is such a common thing that I had designed a
utility function for the job, ``back in the time of S-plus'' ;-)
and called it mult.fig().
I (and few people here) have been using it for several years now
and it may be that it'd be worth to be put into one of those ``misc''
packages {{maybe we should rename ``stepfun'' to ``graphmisc'' and
add a few things, including the "plotCI" one?}}
Anyway here is the code and the doc:
-------------- next part --------------
mult.fig <-
function(nr.plots, mfrow, mfcol,
marP = rep(0,4), mgp = c(1.5,.6,0),
mar = marP + .1 + c(4,4,2,1),
main = NULL,
tit.wid = if (is.null(main)) 0 else 1 + 1.5*cex.main,
quiet = .Device == "postscript",
cex.main = par("cex.main"),
col.main = par("col.main"),
font.main = par("font.main"),
...)
{
## Purpose: 'MULTiple FIGures' incl. TITLE and other good defaults
## -------------------------------------------------------------------------
## Arguments:
## -- Either ONE of the first 3 arguments --
## -------------------------------------------------------------------------
## Author: Martin Maechler, 1990 (UW, Seattle) -- 1995
## -------------------------------------------------------------------------
use.row <- missing(mfcol)
if (use.row)
if (missing(mfrow)) {
if (missing(nr.plots))
stop("must either specify 'nr.plots', 'mfrow' or 'mfcol' !")
else mfrow <- n2mfrow (nr.plots)
}
oma <- c(0, 0, tit.wid, 0)
old.par <<-
if(use.row) par(mfrow = mfrow, oma= oma, mar = mar, mgp= mgp)
else par(mfcol = mfcol, oma= oma, mar = mar, mgp= mgp)
if(!quiet) cat("Execute\n\t par(old.par) \n later to restore graphical par\n")
##---- now go ahead :
if(!is.R())
frame()
if (!is.null(main)) {# Do title *before* first plot!
if(is.R()) plot.new()
mtext(main, side = 3, outer = TRUE,
line = cex.main, # was tit.wid - 4,
cex = cex.main,
font = font.main, col = col.main, ...)
if(is.R()) par(new=TRUE)# reverse `plot.new()' above
}
invisible(list(new.par = par(c("mfrow","mfcol","oma","mar","mgp")),
old.par = old.par))
}
-------------- next part --------------
\name{mult.fig}
\alias{mult.fig}
\title{Plot Setup for MULTiple FIGures, incl. Main Title}
\description{
Easy Setup for plotting multiple figures (in a rectangular layout) on
one page. It allows to specify a main title and uses \emph{smart}
defaults for several \code{\link{par}} calls.
}
\usage{
mult.fig(nr.plots, mfrow, mfcol,
marP = rep(0, 4), mgp = c(1.5, 0.6, 0),
mar = marP + 0.1 + c(4, 4, 2, 1),
main = NULL,
tit.wid = if (is.null(main)) 0 else 1 + 1.5*cex.main,
quiet = .Device == "postscript",
cex.main = par("cex.main"), \dots)
}
\arguments{
\item{nr.plots}{integer; the number of plot figures you'll want to draw.}
\item{mfrow}{\emph{instead} of \code{nr.plots}: integer(2) vector
giving the rectangular figure layout for \code{\link{par}((mfrow= .)}}.}
\item{mfcol}{\emph{instead} of \code{nr.plots}: integer(2) vector
giving the rectangular figure layout for \code{\link{par}((mfcol= .)}}.}
\item{marP}{numeric(4) vector of figure margins to \emph{add}
(``\bold{P}lus'') to default \code{mar}, see below.}
\item{mgp}{argument for \code{\link{par}((mpg= .)}} with a smaller
default than usual.}
\item{mar}{argument for \code{\link{par}((mar= .)}} with a smaller
default than usual, using the \code{marP} argument, see above.}
\item{main}{character. The main title to be used for the whole graphic.}
\item{tit.wid}{numeric; the vertical width to be used for the main title.}
\item{cex.main}{numeric; the character size to be used for the main title.}
\item{quiet}{logical; if \code{TRUE}, do \emph{not} write the reminder
about resetting \code{\link{par}}.}
\item{\dots}{Further arguments to \code{\link{mtext}} for the main title.}
}
\value{
A \code{\link{list}} with two components that are lists themselves, a
subset of \code{\link{par}()},
\item{new.par}{the current \code{par} settings.}
\item{old.par}{the \code{par} \emph{before} the call.}
}
\author{Martin Maechler, UW Seattle, 1990.}
\seealso{\code{\link{par}}, \code{\link{layout}}.}
\examples{
mult.fig(5, main= "Sinus Funktionen verschiedener Frequenzen")
x <- seq(0, 1, len = 201)
for (n in 1:5)
plot(x, sin(n * pi * x), ylab ="", main = paste("n = ",n))
par(old.par)
rr <- mult.fig(mfrow=c(5,1), main= "Sinus Funktionen", cex = 1.5,
marP = - c(0, 1, 2, 0))
for (n in 1:5)
plot(x, sin(n * pi * x), type = 'l', col="red", ylab ="")
str(rr)
par(old.par)
## Look at the par setting *AFTER* the above:
str(do.call("par", as.list(names(rr$new.par))))
}
\keyword{hplot}
-------------- next part --------------
Martin Maechler <maechler at stat.math.ethz.ch> http://stat.ethz.ch/~maechler/
Seminar fuer Statistik, ETH-Zentrum LEO D10 Leonhardstr. 27
ETH (Federal Inst. Technology) 8092 Zurich SWITZERLAND
phone: x-41-1-632-3408 fax: ...-1228 <><
More information about the R-help
mailing list