[Vegan-commits] r443 - in pkg: R inst inst/doc man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sun Jul 6 17:38:21 CEST 2008


Author: jarioksa
Date: 2008-07-06 17:38:21 +0200 (Sun, 06 Jul 2008)
New Revision: 443

Added:
   pkg/R/ordilabel.R
   pkg/R/ordipointlabel.R
   pkg/man/ordilabel.Rd
   pkg/man/ordipointlabel.Rd
Modified:
   pkg/inst/ChangeLog
   pkg/inst/doc/FAQ-vegan.texi
   pkg/inst/doc/intro-vegan.Rnw
Log:
ordilabel & ordipointlabel: new functions for cluttered ordination plots

Added: pkg/R/ordilabel.R
===================================================================
--- pkg/R/ordilabel.R	                        (rev 0)
+++ pkg/R/ordilabel.R	2008-07-06 15:38:21 UTC (rev 443)
@@ -0,0 +1,24 @@
+`ordilabel` <-
+    function(x, display, labels, choices = c(1,2), priority,
+             cex = 0.8, fill = "white", border = NULL,  ...)
+{
+    x <- scores(x, display = display, choices = choices, ...)
+    if (missing(labels))
+        labels <- rownames(x)
+    if (!missing(priority)) {
+        ord <- order(priority)
+        x <- x[ord, ]
+        labels <- labels[ord]
+    }
+    em <- strwidth("m", cex = cex, ...)
+    ex <- strheight("x", cex = cex, ...)
+    w <- (strwidth(labels, cex=cex,...) + em/1.5)/2
+    h <- (strheight(labels, cex = cex, ...) + ex/1.5)/2
+    for (i in 1:nrow(x)) {
+        polygon(x[i,1] + c(-1,1,1,-1)*w[i], x[i,2] + c(-1,-1,1,1)*h[i],
+                col = fill, border = border)
+        text(x[i,1], x[i,2], labels = labels[i], cex = cex, ...)
+    }
+    invisible(x)
+}
+

Added: pkg/R/ordipointlabel.R
===================================================================
--- pkg/R/ordipointlabel.R	                        (rev 0)
+++ pkg/R/ordipointlabel.R	2008-07-06 15:38:21 UTC (rev 443)
@@ -0,0 +1,93 @@
+### Modelled after maptools:::pointLabel.
+`ordipointlabel` <-
+    function(x, display = c("sites", "species"), choices = c(1,2), col=c(1,2),
+             pch=c("o","+"), font = c(1,1), cex=c(0.8, 0.8), add = FALSE, ...)
+{
+    xy <- list()
+    ## Some 'scores' accept only one 'display': a workaround
+    for (nm in display)
+        xy[[nm]] <- scores(x, display = nm, choices = choices, ...)
+    ##xy <- scores(x, display = display, choices = choices, ...)
+    if (length(display) > 1) {
+        col <- rep(col, sapply(xy, nrow))
+        pch <- rep(pch, sapply(xy, nrow))
+        font <- rep(font, sapply(xy, nrow))
+        cex <- rep(cex, sapply(xy, nrow))
+        tmp <- xy[[1]]
+        for (i in 2:length(display))
+            tmp <- rbind(tmp, xy[[i]])
+        xy <- tmp
+    }
+    else {
+        xy <- xy[[1]]
+        if (length(col) < nrow(xy))
+            col <- col[1]
+        if (length(pch) < nrow(xy))
+            pch <- pch[1]
+        if (length(font) < nrow(xy))
+            font <- font[1]
+    }
+    if (!add)
+        pl <- ordiplot(x, display = display, choices = choices, type="n", ...)
+    labels <- rownames(xy)
+    em <- strwidth("m", cex = min(cex), font = min(font))
+    ex <- strheight("x", cex = min(cex), font = min(font))
+    ltr <- em*ex
+    w <- strwidth(labels, cex = cex, font = font) + em
+    h <- strheight(labels, cex = cex, font = font) + ex
+    box <- cbind(w, h)
+    ## offset: 1 up, 2..4 sides, 5..8 corners
+    makeoff <- function(pos, lab) {
+        cbind(c(0,1,0,-1,0.9,0.9,-0.9,-0.9)[pos] * lab[,1]/2,
+              c(1,0,-1,0,0.8,-0.8,-0.8,0.8)[pos] * lab[,2]/2)
+    }
+    ## amount of overlap
+    overlap <- function(xy1, off1, xy2, off2) {
+        pmax(0, pmin(xy1[,1] + off1[,1]/2, xy2[,1] + off2[,1]/2)
+             -pmax(xy1[,1] - off1[,1]/2, xy2[,1] - off2[,1]/2)) *
+              pmax(0, pmin(xy1[,2] + off1[,2]/2, xy2[,2] + off2[,2]/2)
+             -pmax(xy1[,2] - off1[,2]/2, xy2[,2] - off2[,2]/2))
+    }
+    ## indices of overlaps in lower triangular matrix
+    n <- nrow(xy)
+    j <- as.vector(as.dist(row(matrix(0, n, n))))
+    k <- as.vector(as.dist(col(matrix(0, n, n))))
+    ## Find labels that may overlap...
+    maylap <- overlap(xy[j,], 2*box[j,], xy[k,], 2*box[k,]) > 0
+    ## ... and work only with those
+    j <- j[maylap]
+    k <- k[maylap]
+    jk <- sort(unique(c(j,k)))
+    ## SANN: no. of iterations & starting positions
+    nit <- min(48 * length(jk), 10000)
+    pos <- rep(1, n)
+    ## Criterion: overlap + penalty for positions other than directly
+    ## above and especially for corners
+    fn <- function(pos) {
+        off <- makeoff(pos, box)
+        val <- sum(overlap(xy[j,]+off[j,], box[j,], xy[k,]+off[k,], box[k,]))
+        val <- val/ltr + sum(pos>1)*0.1 + sum(pos>4)*0.1
+    }
+    ## Move a label of one point
+    gr <- function(pos) {
+        take <- sample(jk, 1)
+        pos[take] <- sample((1:8)[-pos[take]], 1)
+        pos
+    }
+    ## Simulated annealing
+    sol <- optim(par = pos, fn = fn, gr = gr, method="SANN",
+                 control=list(maxit=nit))
+    if (!add)
+        points(xy, pch = pch, col = col, cex=cex, ...)
+    lab <- xy + makeoff(sol$par, box)
+    text(lab, labels=labels, col = col, cex = cex, font = font,  ...)
+    pl <- list(points = xy)
+    pl$labels <- lab
+    pl$pch <- pch
+    pl$cex <- cex
+    pl$font <- font
+    attr(pl, "optim") <- sol
+    class(pl) <- c("ordipointlabel", class(pl))
+    invisible(pl)
+}
+

Modified: pkg/inst/ChangeLog
===================================================================
--- pkg/inst/ChangeLog	2008-07-06 15:37:30 UTC (rev 442)
+++ pkg/inst/ChangeLog	2008-07-06 15:38:21 UTC (rev 443)
@@ -4,6 +4,15 @@
 
 Version 1.14-7 (opened July 5, 2008)
 
+	* ordilabel: new function for cluttered ordination plots -- text
+	is written on a non-transparent label. Similar to s.label()
+	function in ade4.
+
+	* ordipointlabel: new function for cluttered ordination plots --
+	points are in fixed positions, but their text label is located to
+	avoid overlap. The optimization is based on optim(..., method =
+	"SANN"). Similar to pointLabel function in maptools.
+
 	* permutations: permuted.index2 and associated functions now allow
 	for restricted permutations of strata (i.e. restricted shuffling
 	of the blocks). This changes the acceptable 'type' options and adds
@@ -12,6 +21,7 @@
 
 Version 1.14-6 (closed July 5, 2008)
 
+
 	* permatswap (nestedness.c): translated Peter Solymos's
 	swapcount.R to C. This is still experimental code, and the user
 	interface is undocumented, except here: use method = "Cswap" in

Modified: pkg/inst/doc/FAQ-vegan.texi
===================================================================
--- pkg/inst/doc/FAQ-vegan.texi	2008-07-06 15:37:30 UTC (rev 442)
+++ pkg/inst/doc/FAQ-vegan.texi	2008-07-06 15:38:21 UTC (rev 443)
@@ -547,14 +547,23 @@
 to give to your @code{plot} command.)
 
 @item Use points, and add labels to desired points using @code{identify}
-for ordination graphics, if you do not need to see all labels.  
+for ordination graphics, if you do not need to see all labels. 
 
+ at item Add labels using function @code{ordilabel} which uses
+non-transparent background to the text. The labels still shadow each
+other, but the uppermost labels are readable. Argument @code{priority}
+will help in displaying the most interesting labels. 
+
 @item Use @code{orditorp} function that uses labels only if these can be
 added to a graph without overwriting other labels, and points otherwise,
 if you do not need to see all labels. You must first create an empty
 plot using  @code{plot(..., type="n")}, and then add labels or points
 with @code{orditorp}.  
 
+ at item Use @code{ordipointlabel} which uses points and text labels to the
+points, and tries to optimize the location of the text to minimize the
+overlap. 
+
 @item Use interactive @code{orditkplot} function that lets you drag
 labels of points to better positions if you need to see all labels. Only
 one set of points can be used. 

Modified: pkg/inst/doc/intro-vegan.Rnw
===================================================================
--- pkg/inst/doc/intro-vegan.Rnw	2008-07-06 15:37:30 UTC (rev 442)
+++ pkg/inst/doc/intro-vegan.Rnw	2008-07-06 15:38:21 UTC (rev 443)
@@ -167,9 +167,15 @@
   command.
 \item Use \texttt{select} argument in ordination \texttt{text} and
   \texttt{points} functions to only show the specified items.
+\item Use \texttt{ordilabel} function that uses opaque background to
+  the text: some text labels will be covered, but the uppermost are
+  readable.
 \item Use automatic \texttt{orditorp} function that uses text only if
   this can be done without overwriting previous labels, but points in
   other cases.
+\item Use automatic \texttt{ordipointlabel} function that uses both
+  points and text labels, and tries to optimize the location of the
+  text to avoid overwriting.
 \item Use interactive \texttt{orditkplot} function that draws both
   points and labels for ordination scores, and allows you to drag labels
   to better positions. You can export the results of the edited graph to

Added: pkg/man/ordilabel.Rd
===================================================================
--- pkg/man/ordilabel.Rd	                        (rev 0)
+++ pkg/man/ordilabel.Rd	2008-07-06 15:38:21 UTC (rev 443)
@@ -0,0 +1,51 @@
+\name{ordilabel}
+\alias{ordilabel}
+
+\title{Add Text on Non-transparent Label to an Ordination Plot }
+\description{
+ Function \code{ordilabel} is similar to \code{\link{text}}, but the text is on an
+ opaque label. This can help in crowded ordination plots: you still cannot see
+ all text labels, but at least the uppermost are readable. Argument \code{priority}
+ helps to make the most important labels visible.
+}
+\usage{
+ordilabel(x, display, labels, choices = c(1, 2), priority, cex = 0.8,
+    fill = "white", border = NULL, ...)
+}
+
+\arguments{
+  \item{x}{An ordination object an any object known to \code{\link{scores}}. }
+  \item{display}{Kind of scores displayed (passed to \code{\link{scores}}). }
+  \item{labels}{Optional text used in plots. If this is not given, the text is found from the
+       ordination object.}
+  \item{choices}{Axes shown (passed to \code{\link{scores}}). }
+  \item{priority}{Vector of the same length as the number of labels. The items with
+       high priority will be plotted uppermost. }
+  \item{cex}{ Character expansion for the text (passed to \code{\link{text}}). }
+  \item{fill}{ Background colour of the labels (the \code{col} argument of
+        \code{\link{polygon}}).}
+  \item{border}{The colour and visibilit of the border of the label as defined in
+         \code{\link{polygon}}).}
+  \item{\dots}{Other arguments (passed to \code{\link{text}}). }
+}
+\details{
+ The function may be useful with crowded ordination plots, in particular together with
+  argument \code{priority}. You will not see all text labels, but at least some are
+  readable. Other alternatives to crowded plots are
+  \code{\link{identify.ordiplot}}, \code{\link{orditorp}} and \code{\link{orditkplot}}. 
+}
+
+\author{ Jari Oksanen }
+
+\seealso{ \code{\link{scores}}, \code{\link{polygon}}, \code{\link{text}}. The function is
+ modelled after \code{\link[ade4]{s.label}} in \pkg{ade4} package.}
+\examples{
+data(dune)
+ord <- cca(dune)
+plot(ord, type = "n")
+ordilabel(ord, dis="sites", cex=1.2, font=3, fill="hotpink", col="blue")
+## You may prefer separate plots, but here species as well
+ordilabel(ord, dis="sp", font=2, priority=colSums(dune))
+}
+\keyword{ aplot }
+

Added: pkg/man/ordipointlabel.Rd
===================================================================
--- pkg/man/ordipointlabel.Rd	                        (rev 0)
+++ pkg/man/ordipointlabel.Rd	2008-07-06 15:38:21 UTC (rev 443)
@@ -0,0 +1,69 @@
+\name{ordipointlabel}
+\alias{ordipointlabel}
+
+\title{ Ordination Plots with Points and Optimized Locations for Text }
+\description{
+  The function \code{ordipointlabel} produces ordination plots with
+  points and text label to the points. The points are in the exact
+  location given by the ordination, but the function tries to optimize
+  the location of the text labels to minimize overplotting text. The
+  function may be useful with moderatly crowded ordination plots.
+}
+\usage{
+ordipointlabel(x, display = c("sites", "species"), choices = c(1, 2),
+   col = c(1, 2),  pch = c("o", "+"), font = c(1, 1), 
+   cex = c(0.8, 0.8), add = FALSE, ...)
+}
+
+\arguments{
+  \item{x}{A result object from ordination. }
+  \item{display}{Scores displayed in the plot. }
+  \item{choices}{Axes shown. }
+  \item{col, pch, font, cex}{Colours, point types, font style and
+     character expansion for each kind of scores displayed in the
+     plot. These should be vectors of the same length as the number of
+     items in \code{display}.}
+  \item{add}{ Add to an existing plot. }
+  \item{\dots}{Other rguments passed to \code{\link{points}} and
+  \code{\link{text}}.}
+}
+\details{
+  The function uses simulated annealing (\code{\link{optim}},
+  \code{method = "SANN"}) to optimize the location of the text labels
+  to the points. There are eight possible locations: up, down, sides
+  and corners. There is a weak preference to text right above the
+  point, and a weak avoidance of corner positions. The exact locations
+  and the goodness of solution varies between runs, and there is no
+  guarantee of finding the global optimum. The optimization can take a
+  long time in difficult cases with a high number of potential
+  overlaps. Several sets of scores can be displayed in one plot. 
+
+  The function is modelled after \code{\link[maptools]{pointLabel}} in
+  \pkg{maptools} package (which has chained dependencies of \code{S4}
+  packages). 
+}
+\value{
+  The function returns invisibly an object of class
+  \code{ordipointlabel} with items \code{xy} for coordinates of
+  points, \code{labels} for coordinates of labels, items \code{pch},
+  \code{cex} and \code{font} for graphical parameters of each point or
+  label. In addition, it returns the result of \code{\link{optim}} as
+  an attribute \code{"optim"}. The unit of overlap is the area
+  of character \code{"m"}, and with variable \code{cex} it is the
+  smallest alternative. 
+}
+\references{ See \code{\link[maptools]{pointLabel}} for references. }
+\author{ Jari Oksanen }
+\note{ 
+  The function is designed for ordination graphics, and the
+  optimization works properly with plots of isometric aspect ratio.
+}
+\seealso{ \code{\link[maptools]{pointLabel}} for the model
+  implementation, and \code{\link{optim}} for the optimization. }
+\examples{
+data(varespec)
+ord <- cca(varespec)
+ordipointlabel(ord)
+}
+\keyword{ hplot }
+\keyword{ aplot }



More information about the Vegan-commits mailing list