[R] self-split plot on multiple device

Martin Maechler maechler at stat.math.ethz.ch
Wed Jan 22 11:43:02 CET 2003

>>>>> "AlesSem" == AlessandroSemeria  <AlessandroSemeria at cramont.it>
>>>>>     on Wed, 22 Jan 2003 11:22:35 +0100 writes:

    AlesSem> Hello!  I would plot more than 10 (this number is
    AlesSem> always different) graphics on a figure with layout
    AlesSem> like 'mfrow=c(4,2)'.  There is some existing
    AlesSem> function able to open the right number of device if
    AlesSem> number of graphics is done or I have to build it
    AlesSem> myself with some 'IF.....ELSE.....'?

If you must use the (4,2) layout, you have to do it yourself,
starting a new device {x11() works on Windows and Unix) every 8th plot.
I'm not sure I'd want that for interactive usage.
If you use a non-interactive graphics device such as
postscript()  or pdf() or ...,
a new page is started automatically anyway when the layout is full.

The other approach is to determine the layout automatically from
the number of plots, and there's n2mfrow() since R 1.2.0.
?n2mfrow  starts as

>> Compute Default mfrow From Number of Plots
>> Description:
>>      Easy Setup for plotting multiple figures (in a rectangular layout)
>>      on one page.  It allows to specify a main title and uses smart
>>      defaults for several `par' calls.
>> Usage:
>>      n2mfrow(nr.plots)
>> Arguments:
>>	nr.plots: integer; the number of plot figures you'll want to draw.

I also attach a utility function  mult.fig() using n2mfrow()
that I've also been using for years.
The main extra thing is the easy way using (... main = ..)
for an overall title.

 [ Yes, this is in a package; no, the package is not yet on CRAN
   since it contains too many other undocumented and partly
   outdated functions ..]

mult.fig <-
function(nr.plots, mfrow, mfcol,
         marP = rep(0, 4), mgp = c(1.5, 0.6, 0),
         mar = marP + 0.1 + c(4,4,2,1), oma = c(0,0, tit.wid, 0),
         main = NULL, tit.wid = if (is.null(main)) 0 else 1 + 1.5*cex.main,
         quiet = .Device == "postscript",
         cex.main = par("cex.main"), line.main = cex.main - 1/2,
         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 --
  ###  =========> help(mult.fig)
  ## -------------------------------------------------------------------------
  ## 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)
  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.null(main)) {# Do title *before* first plot!
      if(is.R()) plot.new()
      mtext(main, side = 3, outer = TRUE,
            line = line.main,
            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))

More information about the R-help mailing list