[Rd] legend with multiple columns

Ben Bolker bolker@zoo.ufl.edu
Wed, 31 May 2000 19:10:41 -0400 (EDT)


  I have made a minor hack to "legend" (in R 1.0.0, but I didn't notice
any changes to legend in the 1.0.1 NEWS) to allow the legend to be
formatted in multiple columns, or horizontally (number of columns <-
number of legend items).  (I find this helpful when I have lots of legend
items and not a lot of vertical space to squeeze the legend into.)
  (Another hack I've considered is allowing location to be specified more
flexibly, but I haven't bothered so far.)

  I haven't stringently tested it, but it seems to work.

-- 
Ben Bolker                                  bolker@zoo.ufl.edu
Zoology Department, University of Florida   http://www.zoo.ufl.edu/bolker
318 Carr Hall/Box 118525                    tel: (352) 392-5697
Gainesville, FL 32611-8525                  fax: (352) 392-3704

PATCHES to legend.Rd and legend.R:

*** legend2.txt	Wed May 31 14:45:18 2000
--- legend2.R	Wed May 31 15:02:22 2000
***************
*** 1,7 ****
! function (x, y, legend, fill, col = "black", lty, lwd, pch, bty = "o",
! 	      bg = par("bg"), cex = 1,
!               xjust = 0, yjust = 1, x.intersp = 1, y.intersp = 1, adj = 0,
!               text.width = NULL, merge = do.lines && has.pch, trace = FALSE)
  {
      if(is.list(x)) {
          if(!missing(y)) {               # the 2nd arg maybe really is `legend'
--- 1,9 ----
! function (x, y, legend, fill, col = "black", lty, lwd, pch, bty = "o",
!                        bg = par("bg"), cex = 1,
!                        xjust = 0, yjust = 1, x.intersp = 1, y.intersp = 1, adj = 0,
!                        text.width = NULL, merge = do.lines && has.pch, trace = FALSE,
!                        ncol=1, horiz =FALSE)
!   ## BB hacked for multiple columns
  {
      if(is.list(x)) {
          if(!missing(y)) {               # the 2nd arg maybe really is `legend'
***************
*** 67,72 ****
--- 69,78 ----
      do.lines <- (!missing(lty) && any(lty > 0)) || !missing(lwd)
      n.leg <- length(legend)
  
+     if (horiz && ncol!=1) warning("horizontal specification overrides number of columns")
+     if (horiz) ncol <- n.leg
+     n.legpercol <- ceiling(n.leg / ncol)  ## legends per column
+ 
      if(has.pch <- !missing(pch)) {
  	if(is.character(pch) && nchar(pch[1]) > 1) {
              if(length(pch) > 1)
***************
*** 98,108 ****
  
      } else {## nx == 1
          ## -- (w,h) := (width,height) of the box to draw -- computed in steps
!         h <- n.leg * ychar + yc
!         w <- text.width + (1.5 + x.intersp) * xchar
!         if(!missing(fill))      w <- w + dx.fill
!         if(has.pch && !merge)   w <- w + dx.pch
!         if(do.lines)		w <- w + (2+x.off) * xchar
          ##-- (w,h) are now the final box width/height.
          left <- x      - xjust  * w
          top  <- y + (1 - yjust) * h
--- 104,115 ----
  
      } else {## nx == 1
          ## -- (w,h) := (width,height) of the box to draw -- computed in steps
!         h <- n.legpercol * ychar + yc
!         w0 <- text.width + (x.intersp+1) * xchar
!         if(!missing(fill))      w0 <- w0 + dx.fill
!         if(has.pch && !merge)   w0 <- w0 + dx.pch
!         if(do.lines)		w0 <- w0 + (2+x.off) * xchar
!         w <- w0*ncol+xchar
          ##-- (w,h) are now the final box width/height.
          left <- x      - xjust  * w
          top  <- y + (1 - yjust) * h
***************
*** 112,119 ****
  	rect2(left, top, dx = w, dy = h, col = bg)
  
      ## (xt[],yt[]) := 'current' vectors of (x/y) legend text
!     xt <- rep(left, n.leg) + xchar
!     yt <- top - (1:n.leg) * ychar
  
      if (!missing(fill)) {               #- draw filled boxes -------------
  	fill <- rep(fill, length.out=n.leg)
--- 119,126 ----
  	rect2(left, top, dx = w, dy = h, col = bg)
  
      ## (xt[],yt[]) := 'current' vectors of (x/y) legend text
!     xt <- rep(left, n.leg) + (w0*rep(0:(ncol-1),rep(n.legpercol,ncol)))[1:n.leg] + xchar
!     yt <- top - rep(1:n.legpercol,ncol)[1:n.leg] * ychar
  
      if (!missing(fill)) {               #- draw filled boxes -------------
  	fill <- rep(fill, length.out=n.leg)

*** legend.Rd.old	Wed May 31 19:02:55 2000
--- legend.Rd	Wed May 31 19:05:14 2000
***************
*** 43,48 ****
--- 43,52 ----
      Defaults to the proper value computed by \code{\link{strwidth}(legend)}.}
    \item{merge}{logical; if \code{TRUE}, ``merge'' points and lines but
      not filled boxes.  Defaults to \code{TRUE} if there are points and lines.}
+   \item{ncol}{the number of columns in which to set the legend item (default is 1,
+       a vertical legend.}
+   \item{horiz}{logical; if \code{TRUE}, set the legend horizontally rather than
+      vertically (specifying \code{horiz} overrides the \code{ncol} specification).}
  }
  \description{
    This function can be used to add legends to plots.  Note that a call

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel 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-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._