Today a phytools user contacted me with the following question:
“So far, I have customized my tree in contMap
fairly easily (add.color.bar
, custom
gradients, etc). Is there a way to customize the color of the text for the species names on the tree? For
visualization purposes, I want to embed another factor level of colors within species.”
The answer is, of course, “yes” - it's just a matter of how. I have a related solution on this blog that I
posted some time ago;
however, I thought the specific details of the solution could pose some problems for "contMap"
&
thus it seemed worth re-posting.
I'm going to use real data in the form of body size & ecomorph of Caribbean Anolis lizards:
library(phytools)
data(anoletree)
anoletree
##
## Phylogenetic tree with 82 tips and 81 internal nodes.
##
## Tip labels:
## Anolis_ahli, Anolis_allogus, Anolis_rubribarbus, Anolis_imias, Anolis_sagrei, Anolis_bremeri, ...
##
## The tree includes a mapped, 6-state discrete character with states:
## CG, GB, TC, TG, Tr, Tw
##
## Rooted; includes branch lengths.
svl<-as.matrix(read.csv(
file="http://www.phytools.org/TS2018/data/anole.data.csv",
row.names=1))[,1]
svl
## ahli alayoni alfaroi aliniger
## 4.03913 3.81570 3.52665 4.03656
## allisoni allogus altitudinalis alumina
## 4.37539 4.04014 3.84299 3.58894
## alutaceus angusticeps argenteolus argillaceus
## 3.55489 3.78860 3.97131 3.75787
## armouri bahorucoensis baleatus baracoae
## 4.12168 3.82745 5.05306 5.04278
## barahonae barbatus barbouri bartschi
## 5.07696 5.00395 3.66393 4.28055
## bremeri breslini brevirostris caudalis
## 4.11337 4.05111 3.87415 3.91174
## centralis chamaeleonides chlorocyanus christophei
## 3.69794 5.04235 4.27545 3.88465
## clivicola coelestinus confusus cooki
## 3.75873 4.29797 3.93844 4.09154
## cristatellus cupeyalensis cuvieri cyanopleurus
## 4.18982 3.46201 4.87501 3.63016
## cybotes darlingtoni distichus dolichocephalus
## 4.21098 4.30204 3.92880 3.90855
## equestris etheridgei eugenegrahami evermanni
## 5.11399 3.65799 4.12850 4.16561
## fowleri garmani grahami guafe
## 4.28878 4.76947 4.15427 3.87746
## guamuhaya guazuma gundlachi haetianus
## 5.03695 3.76388 4.18810 4.31654
## hendersoni homolechis imias inexpectatus
## 3.85983 4.03281 4.09969 3.53744
## insolitus isolepis jubar krugi
## 3.80047 3.65709 3.95260 3.88650
## lineatopus longitibialis loysiana lucius
## 4.12861 4.24210 3.70124 4.19891
## luteogularis macilentus marcanoi marron
## 5.10109 3.71576 4.07948 3.83181
## mestrei monticola noblei occultus
## 3.98715 3.77061 5.08347 3.66305
## olssoni opalinus ophiolepis oporinus
## 3.79390 3.83838 3.63796 3.84567
## paternus placidus poncensis porcatus
## 3.80296 3.77397 3.82038 4.25899
## porcus pulchellus pumilis quadriocellifer
## 5.03803 3.79902 3.46686 3.90162
## reconditus ricordii rubribarbus sagrei
## 4.48261 5.01396 4.07847 4.06716
## semilineatus sheplani shrevei singularis
## 3.69663 3.68292 3.98300 4.05800
## smallwoodi strahmi stratulus valencienni
## 5.03510 4.27427 3.86988 4.32152
## vanidicus vermiculatus websteri whitemani
## 3.62621 4.80285 3.91655 4.09748
Unfortunately or data & tree don't exactly match in that the labels of the tree are in the format Genus_species, whereas the data are coded just by specific epithet. Let's make the tree match the data:
tree<-anoletree
tree$tip.label<-setNames(sapply(anoletree$tip.label,
function(x) strsplit(x,"_")[[1]][2]),NULL)
tree
##
## Phylogenetic tree with 82 tips and 81 internal nodes.
##
## Tip labels:
## ahli, allogus, rubribarbus, imias, sagrei, bremeri, ...
##
## The tree includes a mapped, 6-state discrete character with states:
## CG, GB, TC, TG, Tr, Tw
##
## Rooted; includes branch lengths.
ecomorph<-as.factor(getStates(tree,"tips"))
svl<-svl[tree$tip.label]
Now we can make a test plot as follows:
object<-contMap(tree,exp(svl),fsize=c(0.6,0.8))
Now, we need to pull out the information that we need as follows:
lastPP<-get("last_plot.phylo",envir=.PlotPhyloEnv)
## for fun, let's change our contMap gradient
object<-setMap(object,c("blue","green","yellow"))
plot(object,ftype="off",xlim=lastPP$x.lim,fsize=c(0,0.8),
leg.txt="SVL (mm)",legend=2.5,sig=1)
## make sure our discrete character is in the order of our tree
ecomorph<-ecomorph[object$tree$tip.label]
cols<-setNames(RColorBrewer::brewer.pal(
n=length(levels(ecomorph)),
"Dark2"),levels(ecomorph))
for(i in 1:length(ecomorph))
text(lastPP$xx[i],lastPP$yy[i],object$tree$tip.label[i],
pos=4,cex=0.6,col=cols[ecomorph[i]],font=3)
add.simmap.legend(colors=cols,prompt=FALSE,
x=3.7,y=-5.4,vertical=FALSE,fsize=0.8)
That's it.
How do you plot without tip labels?
ReplyDeleteTry ftype="off".
Delete