Sunday, November 1, 2015

Interactive mode for bind.tip & reroot

I recently added interactive modes to both the phytools functions bind.tip (for attaching a single tip to a tree) and reroot (for re-rooting a phylogeny on a node or edge).

Key for both of these updates is the helper function get.treepos. This function uses a plotted tree and the R base function locator to find allow the user to supply a 'location' on a plotted tree. For now, the function only works for "rightward" plotted "phylogram"s (technically, square phylograms or cladograms - but plot.phylo calls these phylograms, and slanted phylograms or cladograms "cladogram"s.

Here is the code for get.treepos, for those people interested in such things:

## get a position in the tree interactively
## written by Liam J. Revell 2015
get.treepos<-function(message=TRUE){
    obj<-get("last_plot.phylo",envir=.PlotPhyloEnv)
    if(obj$type=="phylogram"&&obj$direction=="rightwards"){
        if(message){ 
            cat("Click on the tree position you want to capture...\n")
            flush.console()
        }
        x<-unlist(locator(1))   
        y<-x[2]     
        x<-x[1]
        d<-pos<-c()
        for(i in 1:nrow(obj$edge)){
            x0<-obj$xx[obj$edge[i,]]
            y0<-obj$yy[obj$edge[i,2]]
            if(x<x0[1]||x>x0[2]){
                d[i]<-min(dist(rbind(c(x,y),c(x0[1],y0))),
                    dist(rbind(c(x,y),c(x0[2],y0))))
                pos[i]<-if(x>x0[2]) 0 else diff(obj$xx[obj$edge[i,]])
            } else {
                d[i]<-abs(y0-y)
                pos[i]<-obj$xx[obj$edge[i,2]]-x
            }
        }
        ii<-which(d==min(d))
        list(where=obj$edge[ii,2],pos=pos[ii])
    } else stop("Does not work for the plotted tree type.")
}

Obviously, this is somewhat hard to demonstrate using knitted R markdown, so instead I shot a screen video:

That's it!

No comments:

Post a Comment