Tree Visualization

We will use ggtree to visualize and compare trees.

First we need to install (and load) the packages:

# install once if needed
# if you use Bioconductor: BiocManager::install(c("treeio","ggtree","tidytree"))
# CRAN: install.packages(c("ape","phytools","phangorn","dendextend"))

library(treeio)    # read.raxml(), read.iqtree(), root methods for treedata
library(ggtree)    # plotting and geom_*2 helpers
library(ape)       # read.tree, comparePhylo if desired
library(phytools)  # cophylo tanglegram plotting
library(phangorn)  # RF.dist (Robinson-Foulds) and other tree distances
library(ggplot2)

Now we read the trees:

raxml_td <- read.tree("primatesAA-aligned-muscle-raxml-boostrap.raxml.bestTree")
iq_td    <- read.tree("primatesAA-aligned-muscle.fasta-iqtree-bootstrap.contree")

We need to check if the root is in the right place:

plot(raxml_td)
nodelabels()

raxml_rooted = root(raxml_td, node=33, resolve.root=TRUE)
plot(raxml_rooted)
plot(iq_td)
nodelabels()

iq_rooted = root(iq_td, node=31, resolve.root=TRUE)
plot(iq_rooted)

Now, different tree layouts with ggtree:

ggtree(raxml_rooted, layout = "rectangular") + geom_tiplab()
ggtree(raxml_rooted, layout = "slanted")     + geom_tiplab()
ggtree(raxml_rooted, layout = "circular")    + geom_tiplab2() # tip labels wrapped nicely
ggtree(raxml_rooted, layout = "fan")         + geom_tiplab2(offset = 0.5)

Let’s plot both trees side by side:

# RAxML tree plot
p1 <- ggtree(raxml_rooted) +
  geom_tiplab(size = 3) +
  ggtitle("RAxML Tree")

# IQ-TREE plot
p2 <- ggtree(iq_rooted) +
  geom_tiplab(size = 3) +
  ggtitle("IQ-TREE Tree")

Now combine side by side:

# install.packages("patchwork") if not installed
library(patchwork)

# put them side by side
p1 + p2 + plot_layout(ncol = 2)

Now, let’s try to compare the trees:

comparePhylo(raxml_rooted, iq_rooted) 

And visualize a co-phylogeny:

co <- cophylo(raxml_rooted, iq_rooted, rotate = TRUE)
plot(co, link.lty = "dashed")

Extra: adding more information to the plots

# RAxML tree with bootstrap values
raxml_td <- read.iqtree("primatesAA-aligned-muscle-raxml-boostrap.raxml.support")
raxml_phy <- as.phylo(raxml_td)  # convert to phylo object

# IQ-TREE consensus tree with bootstrap
iq_td <- read.iqtree("primatesAA-aligned-muscle.fasta-iqtree-bootstrap.contree")
iq_phy <- as.phylo(iq_td)

raxml_rooted <- root(raxml_phy, node = 33, resolve.root = TRUE)
iq_rooted    <- root(iq_phy, node = 31, resolve.root = TRUE)

We can do first inspection of the trees:

plot(raxml_rooted); nodelabels()
plot(iq_rooted); nodelabels()

Now we need a function to extract numeric bootstrap values:

extract_bs <- function(tree) {
  if(is.null(tree$node.label)) return(NULL)
  as.numeric(tree$node.label)
}

raxml_bs <- extract_bs(raxml_rooted)
iq_bs    <- extract_bs(iq_rooted)

Now let’s plot side by side:

# Create ggtree objects
p1 <- ggtree(raxml_rooted) +
  geom_tiplab(size = 3) +
  geom_point2(aes(subset = !isTip & !is.na(label),
                  size = as.numeric(label)), color = "steelblue") +
  geom_text2(aes(subset = !isTip & !is.na(label),
                   label = label), hjust=-0.2, vjust=-0.2, size=3) +
 scale_size_continuous(range=c(2,6)) +  # adjust circle sizes
  ggtitle("RAxML Tree")

p2 <- ggtree(iq_rooted) +
  geom_tiplab(size = 3) +
  geom_point2(aes(subset = !isTip & !is.na(label),
                  size = as.numeric(label)), color = "darkred") +
    geom_text2(aes(subset = !isTip & !is.na(label),
                   label = label), hjust=-0.2, vjust=-0.2, size=3) +
 scale_size_continuous(range=c(2,6)) +  # adjust circle sizes
  ggtitle("IQ-TREE Tree")

# Side-by-side layout
p1 + p2 + plot_layout(ncol = 2)

Copyright Solis-Lemus lab © 2022. Distributed by an MIT license.

This site uses Just the Docs, a documentation theme for Jekyll.