diff --git a/NAMESPACE b/NAMESPACE index eaac93f25..bac4e6102 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -100,8 +100,8 @@ importFrom(graphics, abline, arrows, axis, barplot, box, contour, import(permute) ## vegan depends on permute: import everything importFrom(utils, news, vignette, combn, flush.console, modifyList, object.size, read.fortran, read.fwf, str) -importFrom(grDevices, bmp, check.options, chull, col2rgb, dev.off, - heat.colors, jpeg, palette, pdf, png, postscript, rainbow, +importFrom(grDevices, bmp, check.options, chull, col2rgb, dev.hold, dev.flush, + dev.off, heat.colors, jpeg, palette, pdf, png, postscript, rainbow, rgb, svg, tiff, xfig, xy.coords) ## import(grDevices) ## too many functions to be listed separately ## import(lattice) # vegan depends on lattice: import all @@ -249,6 +249,7 @@ S3method(identify, ordiplot) # labels: base S3method(labels, cca) S3method(labels, envfit) +S3method(labels, ordipointlabel) # lines: graphics S3method(lines, fitspecaccum) S3method(lines, permat) diff --git a/R/ordiArgAbsorber.R b/R/ordiArgAbsorber.R index ab9b16443..413a1844f 100644 --- a/R/ordiArgAbsorber.R +++ b/R/ordiArgAbsorber.R @@ -1,3 +1,4 @@ +### List non-graphical arguments used in vegan plot commands `ordiArgAbsorber` <- function(..., shrink, origin, scaling, triangular, - display, choices, const, truemean, FUN) + display, choices, const, truemean, optimize, FUN) match.fun(FUN)(...) diff --git a/R/ordilabel.R b/R/ordilabel.R index 4cdc55fb2..9b22bcbb6 100644 --- a/R/ordilabel.R +++ b/R/ordilabel.R @@ -26,14 +26,13 @@ w <- (strwidth(labels, cex=cex,...) + em/1.5)/2 h <- (strheight(labels, cex = cex, ...) + ex/1.5)/2 if (is.null(col)) - if (!is.null(border)) - col <- border - else - col <- par("fg") + col <- par("fg") col <- rep(col, length=nrow(sco))[ord] - if(!is.null(border)) - border <- rep(border, length=nrow(sco))[ord] + if (is.null(border)) + border <- col + border <- rep(border, length=nrow(sco))[ord] fill <- rep(fill, length=nrow(sco))[ord] + dev.hold() for (i in 1:nrow(sco)) { ordiArgAbsorber(sco[i,1] + c(-1,1,1,-1)*w[i], sco[i,2] + c(-1,-1,1,1)*h[i], @@ -42,6 +41,7 @@ ordiArgAbsorber(sco[i,1], sco[i,2], labels = labels[i], cex = cex, col = col[i], xpd = xpd, FUN = text, ...) } + dev.flush() invisible(x) } diff --git a/R/ordipointlabel.R b/R/ordipointlabel.R index 6f780b4d3..57ab1d2c2 100644 --- a/R/ordipointlabel.R +++ b/R/ordipointlabel.R @@ -1,8 +1,8 @@ ### 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, - select, ...) + pch=c("o","+"), font = c(1,1), cex=c(0.7, 0.7), + add = inherits(x, "ordiplot"), labels, bg, select, ...) { xy <- list() ## Some 'scores' accept only one 'display': a workaround @@ -19,33 +19,50 @@ } } 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 + ld <- length(display) + col <- rep(rep(col, length=ld), sapply(xy, nrow)) + pch <- rep(rep(pch, length=ld), sapply(xy, nrow)) + font <- rep(rep(font, length=ld), sapply(xy, nrow)) + cex <- rep(rep(cex, length=ld), sapply(xy, nrow)) + if (!missing(bg)) + fill <- rep(rep(bg, length=ld), sapply(xy, nrow)) + xy <- do.call(rbind, xy) } else { xy <- xy[[1]] if (length(col) < nrow(xy)) - col <- col[1] + col <- rep(col[1], nrow(xy)) if (length(pch) < nrow(xy)) - pch <- pch[1] + pch <- rep(pch[1], nrow(xy)) + if (length(cex) < nrow(xy)) + cex <- rep(cex[1], length = nrow(xy)) if (length(font) < nrow(xy)) - font <- font[1] + font <- rep(font[1], length = nrow(xy)) + if (!missing(bg) && length(bg) < nrow(xy)) + fill <- rep(bg[1], length = nrow(xy)) } if (!add) - pl <- ordiplot(x, display = display, choices = choices, type="n", ...) - labels <- rownames(xy) + pl <- ordiplot(xy, display = "sites", type="n") + if (!missing(labels)) { + if (length(labels) != nrow(xy)) + stop(gettextf( + "you need %d labels but arg 'labels' only had %d: arg ignored", + nrow(xy), length(labels))) + } else { + 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) + ## bounding box: strwidth/height do not accept vector cex and font + ## and we loop + box <- matrix(0, nrow(xy), 2) + for (i in seq_len(nrow(xy))) { + box[i,1] <- strwidth(labels[i], cex = cex[i], font = font[i]) + + strwidth("m", cex = cex[i], font = font[i]) + box[i,2] <- strheight(labels[i], cex = cex[i], font = font[i]) + + strheight("x", cex = cex[i], font = font[i]) + } ## 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, @@ -69,14 +86,21 @@ 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 + nit <- min(64 * length(jk), 10000) + pos <- ifelse(xy[,2] > 0, 1, 3) + ## Criterion: overlap + penalty for moving towards origin and also + ## for corners. Penalty is mild: max 1 ltr and one-character + ## string > 3*ltr due to padding (em, ex) of the bounding box. fn <- function(pos) { + move <- makeoff(pos, matrix(1, 1, 2)) 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 + val <- sum(overlap(xy[j,,drop=FALSE]+off[j,,drop=FALSE], + box[j,,drop=FALSE], + xy[k,,drop=FALSE]+off[k,,drop=FALSE], + box[k,,drop=FALSE])) + val <- val/ltr + sum(move[,1] * xy[,1] < 0) * 0.4 + + sum(move[,2] * xy[,2] < 0) * 0.4 + + sum(pos > 4) * 0.2 } ## Move a label of one point gr <- function(pos) { @@ -87,15 +111,32 @@ ## 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, ...) - ordiArgAbsorber(xy, pch = pch, col = col, cex = cex, FUN = points, - ...) lab <- xy + makeoff(sol$par, box) + dev.hold() + ## draw optional lab background first so it does not cover points + if (!missing(bg)) { + for(i in seq_len(nrow(lab))) { + polygon(lab[i,1] + c(-1,1,1,-1)*box[i,1]/2.2, + lab[i,2] + c(-1,-1,1,1)*box[i,2]/2.2, + col = fill[i], border = col[i], xpd = TRUE) + ordiArgAbsorber(lab[i,1], lab[i,2], labels = labels[i], + col = col[i], cex = cex[i], font = font[i], + FUN = text, ...) + } + } else { + ordiArgAbsorber(lab, labels=labels, col = col, cex = cex, + font = font, FUN = text, ...) + } + + ## always plot points (heck, the function is ordi*point*label) + ordiArgAbsorber(xy, pch = pch, col = col, cex = cex, FUN = points, + ...) ##text(lab, labels=labels, col = col, cex = cex, font = font, ...) - ordiArgAbsorber(lab, labels=labels, col = col, cex = cex, font = font, - FUN = text, ...) - pl <- list(points = xy) + dev.flush() + if (!inherits(x, "ordiplot")) + pl <- list(points = xy) + else + pl <- x pl$labels <- lab attr(pl$labels, "font") <- font args <- list(tcex = cex, tcol = col, pch = pch, pcol = col, @@ -107,3 +148,11 @@ class(pl) <- c("ordipointlabel", "orditkplot", class(pl)) invisible(pl) } + +### Extract labels: useful if arg labels= is given in ordipointlabel call + +`labels.ordipointlabel` <- + function(object, ...) +{ + rownames(object$labels) +} diff --git a/R/plot.cca.R b/R/plot.cca.R index 98619dce6..bfa16965d 100644 --- a/R/plot.cca.R +++ b/R/plot.cca.R @@ -72,29 +72,34 @@ if (length(g$centroids) > 0 && all(is.na(g$centroids))) NA else g$centroids[, 2], na.rm = TRUE) } - plot(g[[1]], xlim = xlim, ylim = ylim, type = "n", asp = 1, - ...) + ordiArgAbsorber(g[[1]], xlim = xlim, ylim = ylim, type = "n", asp = 1, + FUN = plot, ...) abline(h = 0, lty = 3) abline(v = 0, lty = 3) ## set up lists for graphical parameters GlobalPar <- list("type" = type) dots <- match.call(expand.dots = FALSE)$... - if (!is.null(dots)) + if (!is.null(dots)) { + ## dots par optimize must be eval'ed to force it logical + if (!is.null(dots$optimize)) + dots$optimize <- eval(dots$optimize) GlobalPar <- modifyList(GlobalPar, dots) + } ## Default graphical parameters defParText <- list("species" = list("col" = 2, "cex" = 0.7), "sites" = list("cex" = 0.7), "constraints" = list("col" = "darkgreen", "cex" = 0.7), - "biplot" = list("col" = "blue"), - "regression" = list("col" = "purple4"), - "centroids" = list("col" = "blue")) + "biplot" = list("col" = "blue", "cex" = 1.0), + "regression" = list("col" = "purple4", "cex" = 1.0), + "centroids" = list("col" = "blue", "cex" = 1.0)) defParPoints <- list("species" = list("col" = 2, "cex" = 0.7, "pch" = "+"), "sites" = list("cex" = 0.7, pch = 1), "constraints" = list("col" = "darkgreen", "cex" = 0.7, "pch" = 2), "biplot" = list("col" = "blue"), "regression" = list("col" = "purple4"), - "centroids" = list("col" = "blue", "pch" = "x")) + "centroids" = list("col" = "blue", "pch" = "x", + "cex" = 1.0)) UserPar <- list("species" = spe.par, "sites" = sit.par, "constraints" = con.par, @@ -118,6 +123,17 @@ par <- modifyList(par, GlobalPar) if (!is.null(UserPar[[kind]])) par <- modifyList(par, UserPar[[kind]]) + ## sanitize par combinations + if (score == "points") # points cannot be optimized + par <- modifyList(par, list(optimize = NULL)) + else if (score == "text") { + if (isTRUE(par$optimize)) { + if (isTRUE(par$arrows) || kind %in% c("biplot", "regression")) + message("'optimize = TRUE' and arrows do not mix nicely") + if (is.null(par$pch)) # optimize=TRUE needs points + par <- modifyList(par, list(pch = defParPoints[[kind]]$pch)) + } + } ## add arguments for text/points.ordiplot, remove type par <- modifyList(par, list("x" = g, "what" = kind, "type" = NULL)) do.call(score, par) diff --git a/R/plot.ordipointlabel.R b/R/plot.ordipointlabel.R index 671a14f35..70b765a55 100644 --- a/R/plot.ordipointlabel.R +++ b/R/plot.ordipointlabel.R @@ -7,5 +7,10 @@ plot.ordipointlabel <- function (x, ...) font <- par("font") text(x$labels, rownames(x$labels), cex = x$args$tcex, col = x$args$tcol, font = font, ...) + psize <- par("din") + if(any(abs(psize - x$dim)/x$dim > 0.1)) + message(gettextf( + "original plot size was %.1f x %.1f, current is %.1f x %.1f", + x$dim[1], x$dim[2], psize[1], psize[2])) invisible(x) } diff --git a/R/scores.default.R b/R/scores.default.R index 5de28d851..c32c8d269 100644 --- a/R/scores.default.R +++ b/R/scores.default.R @@ -1,12 +1,15 @@ -"scores.default" <- +`scores.default` <- function (x, choices, display = c("sites", "species", "both"), tidy = FALSE, ...) { - display <- match.arg(display) + if (is.list(x)) { + ## why not display <- match.arg(display, names(x)) ? + display <- match.arg(display) + if (tidy) + display <- "both" + att <- names(x) + } X <- Y <- NULL - if (tidy) - display <- "both" - att <- names(x) if (is.data.frame(x) && all(sapply(x, is.numeric))) x <- as.matrix(x) if (is.list(x) && display %in% c("sites", "both")) { @@ -44,7 +47,6 @@ else { # "both" may be non-chalant: only warn warning("cannot find species scores") } - } else if (is.numeric(x)) { X <- as.matrix(x) diff --git a/R/text.ordiplot.R b/R/text.ordiplot.R index c50029bc9..2d48f5bf7 100644 --- a/R/text.ordiplot.R +++ b/R/text.ordiplot.R @@ -1,6 +1,6 @@ `text.ordiplot` <- - function (x, what, labels, select, arrows = FALSE, length = 0.05, - arr.mul, bg, ...) + function (x, what, labels, select, optimize = FALSE, arrows = FALSE, + length = 0.05, arr.mul, bg, ...) { sco <- scores(x, what) if (!missing(labels)) @@ -21,7 +21,12 @@ arrows(0, 0, sco[,1], sco[,2], length = length, ...) sco <- ordiArrowTextXY(sco, rownames(sco), rescale = FALSE, ...) } - if (missing(bg)) + if (optimize) { + if (missing(bg)) + ordipointlabel(sco, display = what, add = TRUE, ...) + else + ordipointlabel(sco, display = what, bg = bg, add = TRUE, ...) + } else if (missing(bg)) text(sco, labels = rownames(sco), ...) else ordilabel(sco, labels = rownames(sco), fill = bg, ...) diff --git a/man/ordilabel.Rd b/man/ordilabel.Rd index 61860e4b5..73c0e5b70 100644 --- a/man/ordilabel.Rd +++ b/man/ordilabel.Rd @@ -6,42 +6,41 @@ \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 + at least the uppermost ones are readable. Argument \code{priority} helps to make the most important labels visible. Function can be used in pipe after ordination \code{plot} or \code{\link{ordiplot}} command. } \usage{ -ordilabel(x, display, labels, choices = c(1, 2), priority, select, +ordilabel(x, display, labels, choices = c(1, 2), priority, select, cex = 0.8, fill = "white", border = NULL, col = NULL, xpd = TRUE, ...) } \arguments{ \item{x}{An ordination object an any object known to - \code{\link{scores}}. } + \code{\link{scores}}. } \item{display}{Kind of scores displayed (passed to - \code{\link{scores}}). } + \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{select}{Items to be displayed. This can either be a logical vector which is \code{TRUE} for displayed items or a vector of indices of displayed items.} - + \item{cex}{ Character expansion for the text (passed to - \code{\link{text}}). } + \code{\link{text}}). } \item{fill}{ Background colour of the labels (the \code{col} argument of \code{\link{polygon}}).} \item{border}{The colour and visibility of the border of the label as - defined in \code{\link{polygon}}.} - \item{col}{Text colour. Default \code{NULL} will give the value of - \code{border} or \code{par("fg")} if \code{border} is \code{NULL}.} - \item{xpd}{Draw labels also outside the plot region (see - \code{\link{par}}).} + defined in \code{\link{polygon}}. The default is to use text colour + \code{col}.} + \item{col}{Text colour.} + \item{xpd}{Draw labels also outside the plot region.} \item{\dots}{Other arguments (passed to \code{\link{text}}). } } @@ -51,16 +50,17 @@ ordilabel(x, display, labels, choices = c(1, 2), priority, select, as a part of a pipe (\code{|>}) in place of \code{text} after an ordination \code{plot} command (see Examples). - Other alternatives to crowded plots are - \code{\link{identify.ordiplot}}, \code{\link{orditorp}} and - \code{\link[vegan3d]{orditkplot}} (in \pkg{vegan3d} package). + Other alternatives for cluttered plots are + \code{\link{identify.ordiplot}}, \code{\link{orditorp}}, + \code{\link{ordipointlabel}} and \code{\link[vegan3d]{orditkplot}} + (in \pkg{vegan3d} package). } \author{ Jari Oksanen } -\seealso{ \code{\link{scores}}, \code{\link{polygon}}, - \code{\link{text}}. The function is modelled after - \code{s.label} in \pkg{ade4} package.} +\seealso{\code{\link{plot.cca}} and \code{\link{text.ordiplot}} that + can use the function with argument \code{bg}.} + \examples{ data(dune) ord <- cca(dune) diff --git a/man/ordiplot.Rd b/man/ordiplot.Rd index ee139c4ea..63995a8b1 100644 --- a/man/ordiplot.Rd +++ b/man/ordiplot.Rd @@ -7,23 +7,22 @@ \title{ Alternative plot and identify Functions for Ordination } -\description{ - Function \code{ordiplot} is an alternative plotting function which - can be worked with any \pkg{vegan} ordination result and many - non-\pkg{vegan} results. In addition, \code{plot} functions for - \pkg{vegan} ordinations return invisibly an \code{"ordiplot"} result - object, and this allows using \code{ordiplot} support functions with - this result: \code{identify} can be used to add labels to selected - site, species or constraint points, and \code{points} and - \code{text} can add elements to the plot. -} +\description{ Function \code{ordiplot} is an alternative plotting + function which works with any \pkg{vegan} ordination object and many + non-\pkg{vegan} objects. In addition, \code{plot} functions for + \pkg{vegan} ordinations return invisibly an \code{"ordiplot"} object, + and this allows using \code{ordiplot} support functions with this + result: \code{identify} can be used to add labels to selected site, + species or constraint points, and \code{points} and \code{text} can + add elements to the plot, and used in a pipe to add scores into plot + by layers. } \usage{ ordiplot(ord, choices = c(1, 2), type="points", display, xlim, ylim, ...) \method{points}{ordiplot}(x, what, select, arrows = FALSE, length = 0.05, arr.mul, ...) -\method{text}{ordiplot}(x, what, labels, select, arrows = FALSE, - length = 0.05, arr.mul, bg, ...) +\method{text}{ordiplot}(x, what, labels, select, optimize = FALSE, + arrows = FALSE, length = 0.05, arr.mul, bg, ...) \method{identify}{ordiplot}(x, what, labels, ...) } @@ -46,19 +45,22 @@ ordiplot(ord, choices = c(1, 2), type="points", display, xlim, ylim, ...) \code{constraints} (for LC scores), \code{centroids}, \code{biplot} and \code{regression}, and \code{\link{plot.procrustes}} ordination plot has \code{heads} and \code{points}.} - \item{labels}{Optional text used for labels. Row names will be used if - this is missing.} - \item{arrows}{Draw arrows from the origin. This will always be + \item{labels}{Optional text used for labels. Row names of scores will + be used if this is missing.} + \item{optimize}{Optimize locations of text to reduce overlap and plot + point in the actual locations of the scores. Uses + \code{\link{ordipointlabel}}. } + \item{arrows}{Draw arrows from the origin. This will always be \code{TRUE} for biplot and regression scores in constrained - ordination (\code{\link{cca}} etc.) and its value will be ignored. - Setting this \code{TRUE} will draw arrows for any type of scores. This - allows, e.g, using biplot arrows for species. The arrow head will be - at the value of scores, and possible text is moved outwards.} + ordination (\code{\link{cca}} etc.). Setting this \code{TRUE} will + draw arrows for any type of scores. This allows, e.g, using biplot + arrows for species. The arrow head will be at the value of scores, + and possible text is moved outwards.} \item{length}{Length of arrow heads (see \code{\link{arrows}}).} \item{arr.mul}{Numeric multiplier to arrow lenghts; this will also set \code{arrows = TRUE}. The default is to automatically adjust arrow lengths with \code{"biplot"} and \code{"regression"} scores and else - use scores directly.} + use unmodified scores.} \item{bg}{Background colour for labels. If \code{bg} is set, the labels are displayed with \code{\link{ordilabel}} instead of \code{\link{text}}. } @@ -68,11 +70,10 @@ ordiplot(ord, choices = c(1, 2), type="points", display, xlim, ylim, ...) } \details{ - Function \code{ordiplot} draws an ordination diagram using black circles for - sites and red crosses for species. It returns invisibly an object of - class \code{ordiplot} which can be used by \code{identify.ordiplot} - to label selected sites or species, or constraints in - \code{\link{cca}} and \code{\link{rda}}. + + Function \code{ordiplot} draws an ordination diagram with default of + black circles for sites and red crosses for species. It returns + invisibly an object of class \code{ordiplot}. The function can handle output from several alternative ordination methods. For \code{\link{cca}}, \code{\link{rda}} and @@ -86,8 +87,11 @@ ordiplot(ord, choices = c(1, 2), type="points", display, xlim, ylim, ...) with \code{type = "none"} and save the result, and then add sites and species using \code{points.ordiplot} or \code{text.ordiplot} which both pass all their arguments to the corresponding default graphical - functions. The functions can be chained with pipes which allows an - alternative intuitive way of building up plots. + functions. Alternatively, \code{points} and \code{text} can be used in + pipe which allows an intuitive way of building up plots by layers. In + addition, function \code{\link{ordilabel}} and + \code{\link{ordipointlabel}} can be used in pipe after \code{ordiplot} + or other \pkg{vegan} ordination \code{plot} commands. See Examples. } \value{ @@ -107,11 +111,17 @@ ordiplot(ord, choices = c(1, 2), type="points", display, xlim, ylim, ...) Jari Oksanen } -\seealso{ \code{\link{identify}} for basic operations, \code{\link{plot.cca}}, - \code{\link{plot.decorana}}, \code{\link{plot.procrustes}} which also - produce objects for - \code{identify.ordiplot} and \code{\link{scores}} for extracting - scores from non-\code{vegan} ordinations. +\seealso{ + With argument \code{bg} function calls \code{\link{ordilabel}} + to draw text on non-transparent label, and with argument + \code{optimize = TRUE} function calls \code{\link{ordipointlabel}} to + optimize the locations of text labels to minimize + over-plotting. Functions \code{\link{ordilabel}} and + \code{\link{ordipointlabel}} can be used in a pipe together with + \code{ordiplot} methods \code{text} and \code{points}. Function + \code{\link{plot.cca}} uses \code{ordiplot} methods \code{text} and + \code{points} in configurable plots, and these accept the + arguments of the \code{ordiplot} methods described here. } \examples{ diff --git a/man/ordipointlabel.Rd b/man/ordipointlabel.Rd index 6a7aff76a..d1b9f8bad 100644 --- a/man/ordipointlabel.Rd +++ b/man/ordipointlabel.Rd @@ -1,34 +1,49 @@ \name{ordipointlabel} \alias{ordipointlabel} \alias{plot.ordipointlabel} +\alias{labels.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 moderately crowded ordination plots. + +\description{ Function produces ordination plots with points and text + labels to the points. The points are in the fixed locations given by + the ordination, but the locations of the text labels are optimized to + minimize overplotting. The function is useful with moderately 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, select, ...) + cex = c(0.7, 0.7), add = inherits(x, "ordiplot"), labels, bg, select, ...) \method{plot}{ordipointlabel}(x, ...) } \arguments{ - \item{x}{For \code{ordipointlabel()} a result object from an - ordination function. For \code{plot.ordipointlabel} an object - resulting from a call to \code{ordipointlabel()}.} - \item{display}{Scores displayed in the plot. } + \item{x}{For \code{ordipointlabel} a result object from an + ordination function or an ordination plot (possibly in a pipe). For + \code{plot.ordipointlabel} an object from \code{ordipointlabel}.} + \item{display}{Scores displayed in the plot. The default is to show + \code{"sites"} and \code{"species"} that are available to many + ordination methods, but there can be only one set or more than two + set of scores to \code{display}. } \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. } + items in \code{display}, or if there is only one \code{display} + they can be a vector of the length of number items.} + \item{add}{ Add to an existing plot. Default is \code{add = TRUE} when + the function is used in a pipe, and \code{FALSE} usually. } + \item{labels}{Labels used in graph. Species (variable) and SU (row) + names are used if this is missing. Labels must be given in one + vector for all scores of \code{display}. Function \code{labels} can + extract the current name from a saved \code{ordipointlabel} object.} + \item{bg}{Background colour for labels. If this is given, texts is + drawn over non-transparent background. Either a single colour or + vector of colours for each \code{display}, or with one display, for + each label.} \item{select}{Items to be displayed. This can either be a logical vector which is \code{TRUE} for displayed items or a vector of indices of displayed items. \code{select} is only used if a single set of @@ -39,18 +54,22 @@ ordipointlabel(x, display = c("sites", "species"), choices = c(1, 2), \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. + \code{method = "SANN"}) to optimize the locations of the text labels + to the points. There are eight possible locations: up, down, two sides + and four corners. There is a weak preference to text away from zero, + and a weak avoidance of corners. The locations and goodness of + solution varies between runs, and there is no guarantee of finding the + global optimum, or the same text locations twice. 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 can be used in a pipe where the first command is an + ordination \code{plot} command with \code{type = "n"} or to add + points and lablels to save \pkg{vegan} ordination plot object. See + examples. - The function is modelled after \code{pointLabel} in the - \pkg{maptools} package. } \value{ The function returns invisibly an object of class @@ -59,11 +78,11 @@ ordipointlabel(x, display = c("sites", "species"), choices = c(1, 2), \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 + of character \code{"m"}, and with varying graphical parameters the smallest alternative. - There is a \code{plot} method based on \code{orditkplot} but which - does not alter nor reset the graphical parameters via \code{par}. + There is a \code{plot} method based on \code{orditkplot} but it + does not alter or reset the graphical parameters via \code{par}. The result object from \code{ordipointlabel} inherits from \code{\link[vegan3d]{orditkplot}} of \pkg{vegan3d} package, and it may @@ -73,27 +92,22 @@ ordipointlabel(x, display = c("sites", "species"), choices = c(1, 2), margins. } +\seealso{The function is invoked for one set of scores (one + \code{display}) from \code{\link{text.ordiplot}} and + \code{\link{plot.cca}} with argument \code{optimize = TRUE}.} + \author{ Jari Oksanen } -\note{ - The function is designed for ordination graphics, and the - optimization works properly with plots of isometric aspect ratio. -} \examples{ -data(dune) -ord <- cca(dune) -plt <- ordipointlabel(ord) - -## set scaling - should be no warnings! -ordipointlabel(ord, scaling = "sites") - -## plot then add -plot(ord, scaling = "symmetric", type = "n") -ordipointlabel(ord, display = "species", scaling = "symm", add = TRUE) -ordipointlabel(ord, display = "sites", scaling = "symm", add = TRUE) +data(mite, mite.env) +ord <- cca(mite) +ordipointlabel(ord) -## redraw plot without rerunning SANN optimisation -plot(plt) +## Use in a pipe +ord <- cca(mite ~ SubsDens + WatrCont, mite.env) +plot(ord, scaling = "symmetric", type = "n") |> + ordipointlabel() |> # both sites and species + text("biplot", bg = "white", cex=1) } \keyword{ hplot } \keyword{ aplot } diff --git a/man/plot.cca.Rd b/man/plot.cca.Rd index 8c50cc932..2d4906d68 100644 --- a/man/plot.cca.Rd +++ b/man/plot.cca.Rd @@ -127,21 +127,27 @@ the frame).} } -\details{ - Same \code{plot} function will be used for \code{\link{cca}} and - \code{\link{rda}}. This produces a quick, standard plot with current - \code{scaling}. +\details{ Same \code{plot} function will be used for \code{\link{cca}}, + \code{\link{rda}}, \code{\link{dbrda}} and + \code{\link{capscale}}. This produces a quick, standard plot with + current \code{scaling}. The \code{plot} function sets colours (\code{col}), plotting - characters (\code{pch}) and character sizes (\code{cex}) to - default values. The defaults can be changed with global parameters - (\dQuote{dot arguments}) applied to all score types, or a list of - parameters for a specified score type which take precedence over - global parameters and defaults. If you use \code{points} or - \code{text} to add scores to an existing plot, you must be careful to - use exactly same \code{scaling}, \code{choices} and other parameters. - - The \code{plot} function returns (invisible) \code{\link{ordiplot}} + characters (\code{pch}) and character sizes (\code{cex}) to default + values for each score type. The defaults can be changed with global + parameters (\dQuote{dot arguments}) applied to all score types, or a + list of parameters for a specified score type (\code{spe.par}, + \code{sit.par} etc.) which take precedence over global parameters and + defaults. This allows full control of graphics. The scores are plotted + with \code{\link{text.ordiplot}} and \code{\link{points.ordiplot}} and + accept paremeters of these functions. In addition to standard + graphical parameters, text can be plotted over non-transparent label + with arbument \code{bg = }, and location of text can be + optimized to avoid over-writing with argument \code{optimize = TRUE}, + and argument \code{arrows = TRUE} to draw arrows pointing to the + ordination scores. + + the \code{plot} function returns (invisible) \code{\link{ordiplot}} object. You can save this object and use it to construct your plot with \code{ordiplot} functions \code{points} and \code{text}. These functions can be used in pipe (\code{|>}) which allows incremental @@ -156,9 +162,17 @@ data(dune, dune.env); noquote(paste0(sQuote(names(scores(rda(dune ~ ., dune.env)))), collapse=", "))} - (some of these may be missing depending on your model). The first + (some of these may be missing depending on your model and are only + available if given in \code{display}). The first \code{plot} will set the dimensions of graph, and if you do not use - some score type there may be empty white space. + some score type there may be empty white space. In addition to + \code{\link{ordiplot}} \code{text} and \code{points}, you can also use + \code{\link{ordilabel}} and \code{\link{ordipointlabel}} in a + pipe. Unlike in basic \code{plot}, there are no defaults for score + types, but all graphical parameters must be set in the command in + pipe. On the other hand, there may be more flexibility in these + settings than in \code{plot} arguments, in particular in + \code{\link{ordilabel}} and \code{\link{ordipointlabel}}. Environmental variables receive a special treatment. With \code{display="bp"}, arrows will be drawn. These are labelled with @@ -186,6 +200,14 @@ standard and more easily interpreted, and regression arrows should be used only if you know that you need them. + The ordination object has \code{text} and \code{points} methods that + can be used to add items to an existing plot from the ordination + result directly. These should be used with extreme care, because you + must set scaling and other graphical parameters exactly similarly as + in the original \code{plot} command. It is best to avoid using these + historic functions and instead configure \code{plot} command or use + pipe. + Palmer (1993) suggested using linear constraints (\dQuote{LC scores}) in ordination diagrams, because these gave better results in simulations and site scores (\dQuote{WA scores}) are a step from @@ -195,18 +217,24 @@ little affected. Therefore the \code{plot} function uses site scores (\dQuote{WA scores}) as the default. This is consistent with the usage in statistics and other functions in \R (\code{\link[MASS]{lda}}, - \code{\link{cancor}}). } \value{ The \code{plot} function returns + \code{\link{cancor}}).} + +\value{ The \code{plot} function returns invisibly a plotting structure which can be used by function \code{\link{identify.ordiplot}} to identify the points or other - functions in the \code{\link{ordiplot}} family. } + functions in the \code{\link{ordiplot}} family or in a pipe to add new + graphicael elements with \code{\link{ordiplot}} \code{text} and + \code{points} or with \code{\link{ordilabel}} and + \code{\link{ordipointlabel}}. } \author{Jari Oksanen } \seealso{ - The function builds upon \code{\link{ordiplot}} and its \code{text} - and \code{points} functions. See these to find available graphical - parameters. Function \code{\link{ordilabel}} can also be used within a - pipe. + The function builds upon \code{\link{ordiplot}} and its + \code{text} and \code{points} functions. See these to find new + graphical parameters such as \code{arrows} (for drawing arrows), + \code{bg} (for writing text on non-transparent label) and + \code{optimize} (to move text labels of points to avoid overwriting). } \examples{ diff --git a/man/vegan-internal.Rd b/man/vegan-internal.Rd index 72cf297ac..818278f98 100644 --- a/man/vegan-internal.Rd +++ b/man/vegan-internal.Rd @@ -29,7 +29,7 @@ ordiTerminfo(d, data) ordiNAexclude(x, excluded) ordiNApredict(omit, x) ordiArgAbsorber(..., shrink, origin, scaling, triangular, - display, choices, const, truemean, FUN) + display, choices, const, truemean, optimize, FUN) centroids.cca(x, mf, wt) getPermuteMatrix(perm, N, strata = NULL) howHead(x, ...)