Skip to content

margin text mtext

3 messages · Christian Schulz, Paul Murrell, Martin Maechler

#
Hi all,

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.

 >uname -a
SunOS fluke 5.7 Generic_106541-12 sun4d sparc SUNW,SPARCserver-1000
R-1.2.3

Thanks for hints
--christian


Dr.sc.math.Christian W. Hoffmann
Mathematics and Statistical Computing
Landscape Modeling and Web Applications
Swiss Federal Research Institute WSL 
Zuercherstrasse 111
CH-8903 Birmensdorf, Switzerland
phone: ++41-1-739 22 77    fax: ++41-1-739 22 15
e-mail: christian.hoffmann_at_wsl.ch__prevent_spamming
www: http://www.wsl.ch/staff/christian.hoffmann/

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
2 days later
#
Hi
A couple of things ...
(i)  the code within on.exit() is not executed until the function exits
which is why your margins are not affected during the function call
(ii)  you should probably be using par(mfrow) instead of screen() et al
A suggested modification of your function is:

plot.pcaX <- function(tit,lab) {
  oldpar <- par(oma=c(4, 2, 4, 2), mar = c(4, 4, 2, 1)) # ??
  on.exit(par(oldpar)) # ??
  par(mfrow=c(3,3))
  for (i in 1:9) { 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)
}

Hope that helps

Paul


-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
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			<><