[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