View source: R/aggr_trait_map.R
aggr.trait.map | R Documentation |
This function is a wrapper of the plot.mapping and thermo.var functions. Its goal is to take the arithmetic mean of the values of a trait reconstructed for taxa following different methods and/or method parameters. Such arithmetic mean is considered as the "aggregated" method and is displayed by coloring the tree branches. Additional information about the variation between methods can be displayed by "thermometers" (see also tiplabels and nodelabels) for each taxon, with a color gradient for the value reconstructed for the array of methods.
aggr.trait.map(tree,values,type=c("taxa","branch"),plot=c("methods","groups","aggr"),aggr=TRUE,groups=NULL,
order=c("phylo","names","edge"),cols.args,lims=c("local","groups","global","asym","sym0","symx"),
disag=FALSE,disag.type=c("sign","steps"),return.disag=FALSE,thermo=TRUE,
plot.mapping.args=NULL,thermo.var.args=NULL)
tree |
The phylogenetic tree to put "thermometers" on. |
values |
The data to "map" onto the phylogenetic tree and that the colors have to follow; can be a data frame or a matrix with taxa as rows and methods as columns. |
type |
Optional character. If |
plot |
Optional character. Whether to plot all methods ( |
aggr |
Optional. The reference |
groups |
Optional. If |
order |
Optional character. To specify the order of the |
cols.args |
Optional list. A list of arguments for the reference color palette to be passed to the scale.palette function. These arguments are the palette resolution |
lims |
Optional. The type or values of limits for the "mapping" and/or the "thermometers" to consider. If a character, limits can encompass the range of plotted values only ( |
disag |
Optional. If |
disag.type |
Optional. If |
return.disag |
If |
thermo |
Optional logical. Whether to plot "thermometers" to account for values variation or not. Set to |
plot.mapping.args |
Optional list. Arguments to be passed to plot.mapping that are not informed from elsewhere. These are the plot title ( |
thermo.var.args |
Optional list. Argmuents to be passed to thermo.var that are not informed from elsewhere. These are the resolution for "thermometers" ( |
require(ape)
require(phytools)
# Get a random tree
set.seed(10)
tree<-rtree(50)
# Get a random distribution of values for tips
tipvalues<-matrix(ncol=5,nrow=Ntip(tree))
set.seed(20)
tipvalues[,1]<-fastBM(tree)
# Modify a bit these values, with about one half of variation, to simulate different methods
for(i in 2:5){
set.seed(i+11)
tipvalues[,i]<-sapply(tipvalues[,1],function(x){x+runif(1,-0.5,0.5)*diff(range(tipvalues[,1]))})
}
rownames(tipvalues)<-tree$tip.label
# Get the ancestral reconstructions for each "method"
ancvalues<-matrix(ncol=5,nrow=Nnode(tree))
for(i in 1:5){
set.seed(i*2)
ancvalues[,i]<-fastAnc(tree,tipvalues[,i])
}
# Collate tips and nodes values
values<-rbind(tipvalues,ancvalues)
# Map all "methods" + average values (all "methods" for each tip) and get an idea of the variation across "methods"
layout(get.grid(ncol(values)+1))
aggr.trait.map(tree,values,type="taxa",aggr=FALSE)
# All plots have their own color range according to their values, but there are obviously some discrepancies, let's use the total data range instead
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,lims="global")
# The range of values being not especially controlled but having values above and below zero, let's have the first condition ("local" color ranges) with now a symmetric color scale
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,lims="sym0")
# Let's now have a symmetrical color range indexed on all values
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,lims=c("global","sym0"))
# The data are not necessarily distributed around zero, let's have a symmetric color range but around the "real" middle of the values range, to have closer fidelity of the colors to the values
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,lims=c("global","symx",mean(range(values))))
# Let's repeat this but this time using "local" color ranges for "mappings" (to have maximal palette range for each), still keeping a symmetric color palette (using thus "symx") centered on "local" data arithmetic mean (not providing the "x" that will be automatically calculated)
# and "global" color ranges for "thermometers" (to check the "aggregated" values position, with necessarily the colors of the "thermometers" not matching that of the "aggregated mapping")
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,lims=list(c("local","symx"),c("global","symx",mean(range(values)))))
# Now let's consider there are two groups or methods: one with the first tree, one with the two last. Let's plot them
layout(get.grid(2))
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,lims="global",plot="groups",groups=c(1,1,1,2,2))
# Let's now see them with all methods and with global aggregate
layout(get.grid(ncol(values)+3))
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,lims="global",plot=c("methods","groups","aggr"),groups=c(1,1,1,2,2))
# Get trait values changes between taxa
changes<-apply(values,2,function(x){x[tree$edge[,2]]-x[tree$edge[,1]]})
# Do as previously for values changes
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge")
# This time, we can now that changes are negative or positive, so with a "center" around zero; let's have a symmetric color range around zero
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims="sym0")
# Due to a very high extreme we lost a lot of finer resolution, so let's do the same but with
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("global","sym0"))
# As it stands, it converts changes values in three colors, hence separating distribution (governed by limits) in three ranges of equal width.
# However, we could be interested in having an uneven repartition since most branches are in the second condition (color yellow), i.e., close to a zero value.
# Let's have the same as previously but with colors distributed so to have three even classes of colors.
# To do so, we need to indicate that the colors do not represent equal thirds between data limits but a custom width (representing, here, one third of values distribution)
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("global","sym0"),plot.mapping.args = list("branch.col.freqs"="equal","branch.col.freqs.type"="proportion"))
# Do the same with a finer color resolution
cols.args<-list("fun"="scale.palette","ncols"=1000,"cols"=c("blue","yellow","red"))
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",cols.args=cols.args,lims=c("local","sym0"),plot.mapping.args = list("branch.col.freqs"="equal","branch.col.freqs.type"="proportion"))
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",cols.args=cols.args,lims=c("global","sym0"),plot.mapping.args = list("branch.col.freqs"="equal","branch.col.freqs.type"="proportion"))
# Now do the same with the values in the 5% range around zero being in yellow
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("local","sym0"),plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="width"))
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("global","sym0"),plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="width"))
# Now do the same with the values in the 5% range around zero being in yellow before doing the color gradient (with therefore more colors, the values in the 5% range around zero being the yellowests)
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("local","sym0"),cols.args=cols.args,plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="width"))
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("global","sym0"),cols.args=cols.args,plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="width"))
# Now do the same with the 5% central values being in yellow
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("local","sym0"),plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="proportion"))
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("global","sym0"),plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="proportion"))
# Now do the same with the 5% central values being in yellow before doing the color gradient (with therefore more colors, the 5% central values being the yellowests)
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("local","sym0"),cols.args=cols.args,plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="proportion"))
aggr.trait.map(tree,changes,type="branch",aggr=FALSE,order="edge",lims=c("global","sym0"),cols.args=cols.args,plot.mapping.args = list("branch.col.freqs"=c(0.475,0.05,0.475),"branch.col.freqs.type"="proportion"))
# Get signs of changes
signs<-apply(changes,c(1,2),sign)
aggr.trait.map(tree,signs,type="branch",aggr=FALSE,order="edge",disag=TRUE)
# Now signs are too much present, let's get some tolerance and set as zero value the ones close to zero
range(changes) # Let's take -0.5 and 0.5 as bounds
signs<-apply(changes,c(1,2),function(x){if(x<0.5&x>(-0.5)){x<-0}else{sign(x)}})
aggr.trait.map(tree,signs,type="branch",aggr=FALSE,order="edge",disag=TRUE)
# Let's do same with -1 and 1 as bounds, and with disagreeing branches in light gray, to first see agreeing branches
signs<-apply(changes,c(1,2),function(x){if(x<1&x>(-1)){x<-0}else{sign(x)}})
aggr.trait.map(tree,signs,type="branch",aggr=FALSE,order="edge",disag="lightgray")
# Now let's get the disagreeing branches
disag<-aggr.trait.map(tree,signs,type="branch",aggr=FALSE,order="edge",disag="lightgray",return.disag=TRUE)
disag[which(disag)]
# Sort values with custom order
order<-sample(1:nrow(values),nrow(values))
# Get aggregated values relying on their names
tree$node.label<-as.character((1:Nnode(tree))+Ntip(tree)) # Adding names for nodes
rownames(values)<-c(tree$tip.label,tree$node.label) #Adding node labels as rownames to values
par(mfrow=c(1,1))
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,plot="aggr",plot.mapping.args=list("title"="reference"))
aggr.trait.map(tree,values[order,],type="taxa",aggr=FALSE,plot="aggr",order="names",plot.mapping.args=list("title"="relying on names"))
# Rely on the given order, still having names for nodes
aggr.trait.map(tree,values[order,],type="taxa",aggr=FALSE,plot="aggr",order=order,plot.mapping.args=list("title"="relying on taxa names order"))
aggr.trait.map(tree,values[order,],type="taxa",aggr=FALSE,plot="aggr",order=order,plot.mapping.args=list("title"="relying on numeric order with node labels"))
# Rely on the given order but without node names
tree$node.label<-NULL
rownames(values)<-c(tree$tip.label,rep("",Nnode(tree)))
aggr.trait.map(tree,values[order,],type="taxa",aggr=FALSE,plot="aggr",order=order,plot.mapping.args=list("title"="relying on numeric order without node labels"))
# Manually add aggregated values a priori and specify it
aggr.trait.map(tree,values,type="taxa",aggr=FALSE,plot="aggr",plot.mapping.args=list("title"="reference"))
aggr<-apply(values,1,mean)
# First with adding aggregated values as the last column
values2<-cbind(values,"aggr"=aggr)
aggr.trait.map(tree,values2,type="taxa",aggr=TRUE,plot="aggr",plot.mapping.args=list("title"="aggr as default (last column)"))
# Second, mixing values columns and specify which is the aggregated one by its name or its number
values3<-values2[,sample(1:ncol(values2),ncol(values2))]
aggr.trait.map(tree,values2,type="taxa",aggr="aggr",plot="aggr",plot.mapping.args=list("title"="aggr somewhere, specifying it by its name"))
aggr.trait.map(tree,values3,type="taxa",aggr=which(colnames(values3)=="aggr"),plot="aggr",plot.mapping.args=list("title"="aggr somewhere, specifying it by its position"))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.