]> git.donarmstrong.com Git - ape.git/commitdiff
new trex() + kronoviz() and bug fixing in identify.phylo()
authorparadis <paradis@6e262413-ae40-0410-9e79-b911bd7a66b7>
Wed, 23 Mar 2011 12:28:30 +0000 (12:28 +0000)
committerparadis <paradis@6e262413-ae40-0410-9e79-b911bd7a66b7>
Wed, 23 Mar 2011 12:28:30 +0000 (12:28 +0000)
git-svn-id: https://svn.mpl.ird.fr/ape/dev/ape@153 6e262413-ae40-0410-9e79-b911bd7a66b7

ChangeLog
DESCRIPTION
R/identify.phylo.R
R/plot.phylo.R
man/identify.phylo.Rd
man/kronoviz.Rd [new file with mode: 0644]
man/trex.Rd [new file with mode: 0644]

index cfc7f0772abfdbe1daeaf05ecf61bed37e113b9a..5f6172d24d48c3f8a82f69cc8258ce1dbd9df2f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,32 @@
                CHANGES IN APE VERSION 2.7-1
 
 
+NEW FEATURES
+
+    o The new function trex does tree exploration with multiple
+      graphical devices.
+
+    o The new function kronoviz plots several rooted (dated) trees on
+      the scale scale.
+
+    o identify.phylo() has a new option 'quiet' (FALSE by default).
+
+
 BUG FIXES
 
     o A bug was introduced in read.nexus() in ape 2.7.
 
     o image.DNAbin() did not colour correctly the bases if there were
-      '-' and no 'N' in the alignment.
+      some '-' and no 'N'.
+
+    o identify.phylo() returned a wrong answer when the x- and y-scales
+      are very different.
+
+
+OTHER CHANGES
+
+    o identify.phylo() now returns NULL if the user right-(instead of
+      left-)clicks (an error was returned previously).
 
 
 
index 3c499852f1bc0532eaf94d57ef7bbb0639d3c639..32054d419cf3b963ae83df5ec1285a689ddbb794 100644 (file)
@@ -1,6 +1,6 @@
 Package: ape
 Version: 2.7-1
-Date: 2011-03-18
+Date: 2011-03-22
 Title: Analyses of Phylogenetics and Evolution
 Author: Emmanuel Paradis, Ben Bolker, Julien Claude, Hoa Sien Cuong, Richard Desper, Benoit Durand, Julien Dutheil, Olivier Gascuel, Christoph Heibl, Daniel Lawson, Vincent Lefort, Pierre Legendre, Jim Lemon, Yvonnick Noel, Johan Nylander, Rainer Opgen-Rhein, Klaus Schliep, Korbinian Strimmer, Damien de Vienne
 Maintainer: Emmanuel Paradis <Emmanuel.Paradis@ird.fr>
index 130a8788c658b35471af23895981068e9d622e58..64ecc38734dd2be60e6dd72edf87eccbe45be497 100644 (file)
@@ -1,19 +1,31 @@
-## identify.phylo.R (2008-02-28)
+## identify.phylo.R (2011-03-23)
 
 ##   Graphical Identification of Nodes and Tips
 
-## Copyright 2008 Emmanuel Paradis
+## Copyright 2008-2011 Emmanuel Paradis
 
 ## This file is part of the R-package `ape'.
 ## See the file ../COPYING for licensing issues.
 
 identify.phylo <- function(x, nodes = TRUE, tips = FALSE,
-                           labels = FALSE, ...)
+                           labels = FALSE, quiet = FALSE, ...)
 {
-    cat("Click close to a node of the tree...\n")
+    if (!quiet)
+        cat("Click close to a node of the tree...\n")
     xy <- locator(1)
+    if (is.null(xy)) return(NULL)
     lastPP <- get("last_plot.phylo", envir = .PlotPhyloEnv)
-    d <- sqrt((xy$x - lastPP$xx)^2 + (xy$y - lastPP$yy)^2)
+    ## rescale the coordinates (especially if the x- and
+    ## y-scales are very different):
+    pin <- par("pin")
+    rescaleX <- pin[1]/max(lastPP$xx)
+    xx <- rescaleX * lastPP$xx
+    rescaleY <- pin[2]/max(lastPP$yy)
+    yy <- rescaleY * lastPP$yy
+    xy$x <- rescaleX * xy$x
+    xy$y <- rescaleY * xy$y
+    ## end of rescaling
+    d <- (xy$x - xx)^2 + (xy$y - yy)^2 # no need to sqrt()
     NODE <- which.min(d)
     res <- list()
     if (NODE <= lastPP$Ntip) {
index b2273ca2ef1679a05924abc2541aac249e556f9d..18bba88509dd0bab1e37b91d3b274c26a6aee316 100644 (file)
@@ -1,4 +1,4 @@
-## plot.phylo.R (2011-02-17)
+## plot.phylo.R (2011-03-23)
 
 ##   Plot Phylogenies
 
@@ -609,3 +609,78 @@ plot.multiPhylo <- function(x, layout = 1, ...)
     }
     for (i in 1:length(x)) plot(x[[i]], ...)
 }
+
+trex <- function(phy, title = TRUE, subbg = "lightyellow3",
+                 return.tree = FALSE, ...)
+{
+    lastPP <- get("last_plot.phylo", envir = .PlotPhyloEnv)
+    devmain <- dev.cur() # where the main tree is plotted
+
+    restore <- function() {
+        dev.set(devmain)
+        assign("last_plot.phylo", lastPP, envir = .PlotPhyloEnv)
+    }
+
+    on.exit(restore())
+    NEW <- TRUE
+    cat("Click close to a node. Right-click to exit.\n")
+    repeat {
+        x <- identify.phylo(phy, quiet = TRUE)
+        if (is.null(x)) return(invisible(NULL)) else {
+            x <- x$nodes
+            if (is.null(x)) cat("Try again!\n") else {
+                if (NEW) {
+                    dev.new()
+                    par(bg = subbg)
+                    devsub <- dev.cur()
+                    NEW <- FALSE
+                } else dev.set(devsub)
+
+                tr <- extract.clade(phy, x)
+                plot(tr, ...)
+                if (is.character(title)) title(title)
+                else if (title) {
+                     tl <-
+                         if (is.null(phy$node.label))
+                         paste("From node #", x, sep = "")
+                         else paste("From", phy$node.label[x - Ntip(phy)])
+                     title(tl)
+                }
+                if (return.tree) return(tr)
+                restore()
+            }
+        }
+    }
+}
+
+kronoviz <- function(x, layout = length(x), horiz = TRUE, ...)
+{
+    par(mar = rep(0.5, 4), oma = rep(2, 4))
+    rts <- sapply(x, function(x) branching.times(x)[1])
+    maxrts <- max(rts)
+    lim <- cbind(rts - maxrts, rts)
+    Ntree <- length(x)
+    Ntips <- sapply(x, Ntip)
+    if (horiz) {
+        nrow <- layout
+        w <- 1
+        h <- Ntips
+    } else {
+        nrow <- 1
+        w <- Ntips
+        h <- 1
+    }
+    layout(matrix(1:layout, nrow), widths = w, heights = h)
+    if (layout > Ntree && !par("ask")) {
+        par(ask = TRUE)
+        on.exit(par(ask = FALSE))
+    }
+    if (horiz) {
+        for (i in 1:Ntree)
+            plot(x[[i]], x.lim = lim[i, ], ...)
+    } else {
+        for (i in 1:Ntree)
+            plot(x[[i]], y.lim = lim[i, ], direction = "u", ...)
+    }
+    axisPhylo(if (horiz) 1 else 4) # better if the deepest tree is last ;)
+}
index 166653aac4f9ac96031b5356af4d866dcc46fbd8..c7fd7af0a00e865f47ddd9238cab7d5902a1bb1f 100644 (file)
@@ -3,7 +3,7 @@
 \title{Graphical Identification of Nodes and Tips}
 \usage{
 \method{identify}{phylo}(x, nodes = TRUE, tips = FALSE,
-                  labels = FALSE, ...)
+                  labels = FALSE, quiet = FALSE, ...)
 }
 \arguments{
   \item{x}{an object of class \code{"phylo"}.}
@@ -12,6 +12,8 @@
     information.}
   \item{labels}{a logical specifying whether to return the labels; by
     default only the numbers are returned.}
+  \item{quiet}{a logical controlling whether to print a message inviting
+    the user to click on the tree.}
   \item{\dots}{further arguments to be passed to or from other methods.}
 }
 \description{
diff --git a/man/kronoviz.Rd b/man/kronoviz.Rd
new file mode 100644 (file)
index 0000000..596fc54
--- /dev/null
@@ -0,0 +1,33 @@
+\name{kronoviz}
+\alias{kronoviz}
+\title{Plot Multiple Chronograms on the Same Scale}
+\description{
+  The main argument is a list of (rooted) trees which are plotted on the
+  same scale.
+}
+\usage{
+kronoviz(x, layout = length(x), horiz = TRUE, ...)
+}
+\arguments{
+  \item{x}{a list of (rooted) trees of class \code{"phylo"}.}
+  \item{layout}{an integer giving the number of trees plotted
+    simultaneously; by default all.}
+  \item{horiz}{a logical specifying whether the trees should be plotted
+    rightwards (the default) or upwards.}
+  \item{\dots}{further arguments passed to \code{plot.phylo}.}
+}
+\details{
+  The size of the individual plots is proportional to the size of the
+  trees.
+}
+\value{NULL}
+\author{Emmanuel Paradis}
+\seealso{
+  \code{\link{plot.phylo}}
+}
+\examples{
+TR <- replicate(10, rcoal(sample(11:20, size = 1)), simplify = FALSE)
+kronoviz(TR)
+kronoviz(TR, horiz = FALSE, type = "c", show.tip.label = FALSE)
+}
+\keyword{hplot}
diff --git a/man/trex.Rd b/man/trex.Rd
new file mode 100644 (file)
index 0000000..e05ed42
--- /dev/null
@@ -0,0 +1,69 @@
+\name{trex}
+\alias{trex}
+\title{Tree Explorer With Multiple Devices}
+\description{
+  This functions requires a plotted tree: the user is invited to click
+  close to a node and the corresponding subtree (or clade) is plotted on
+  a new window.
+}
+\usage{
+trex(phy, title = TRUE, subbg = "lightyellow3",
+     return.tree = FALSE, ...)
+}
+\arguments{
+  \item{phy}{an object of class \code{"phylo"}.}
+  \item{title}{a logical or a character string (see details).}
+  \item{subbg}{a character string giving the background colour for the
+    subtree.}
+  \item{return.tree}{a logical: if \code{TRUE}, the subtree is returned
+    after being plotted and the operation is stopped.}
+  \item{\dots}{further arguments to pass to \code{plot.phylo}.}
+}
+\details{
+  This function works with a tree (freshly) plotted on an interactive
+  graphical device (i.e., not a file). After calling \code{trex}, the
+  user clicks close to a node of the tree, then the clade from this node
+  is plotted on a \emph{new} window. The user can click as many times on
+  the main tree: the clades are plotted successively on the \emph{same}
+  new window. The process is stopped by a right-click. If the user clicks
+  too close to the tips, a message ``Try again!'' is printed.
+
+  Each time \code{trex} is called, the subtree is plotted on a new
+  window without closing or deleting those possibly already
+  plotted. They may be distinguished with the options \code{title}
+  and/or \code{subbg}.
+
+  In all cases, the device where \code{phy} is plotted is the active
+  window after the operation. It should \emph{not} be closed during the
+  whole process.
+
+  If \code{title = TRUE}, a default title is printed on the new window
+  using the node label, or the node number if there are no node labels
+  in the tree. If \code{title = FALSE}, no title is printed. If
+  \code{title} is a character string, this is used for the title.
+}
+\value{
+  an object of class \code{"phylo"} if \code{return.tree = TRUE}
+}
+\author{Emmanuel Paradis}
+\seealso{
+  \code{\link{plot.phylo}}, \code{\link{identify.phylo}}
+}
+\examples{
+\dontrun{
+tr <- rcoal(1000)
+plot(tr, show.tip.label = FALSE)
+trex(tr) # left-click as many times as you want, then right-click
+tr <- makeNodeLabel(tr)
+trex(tr, subbg = "lightgreen") # id.
+
+## generate a random colour with control on the darkness:
+rRGB <- function(a, b)
+    rgb(runif(1, a, b), runif(1, a, b), runif(1, a, b))
+
+### with a random pale background:
+trex(tr, subbg = rRGB(0.8, 1))
+## the above can be called many times...
+graphics.off() # close all graphical devices
+}}
+\keyword{hplot}