Thursday, November 30, 2023

Graphing a "simmap" phylogeny with different line types for different mapped regimes or states

The phytools plotting method for the "simmap" object class has no built-in capability to graph regimes with different line-styles. This means that if we want our plotted tree with mapped regimes or characters to be accessible to the colorblind, or readable when printed in grey scale, we must use a color palette that renders into grey without losing the ability to discriminate colors.

There is, however, a clever way that we can simulate different line types for different regimes or character states in a "simmap" object, and that is by overplotting our tree after updating par()$lty.

Here’s a simple demo of what I mean.

library(phytools)
data("sunfish.tree")
sunfish.tree
## 
## Phylogenetic tree with 28 tips and 27 internal nodes.
## 
## Tip labels:
## 	Acantharchus_pomotis, Lepomis_gibbosus, Lepomis_microlophus, Lepomis_punctatus, Lepomis_miniatus, Lepomis_auritus, ...
## 
## The tree includes a mapped, 2-state discrete character
## with states:
## 	non, pisc
## 
## Rooted; includes branch lengths.

This tree is already a "simmap" object, so let’s plot it as follows:

cols<-setNames(c(palette()[4],"transparent"),c("non","pisc"))
plot(sunfish.tree,cols,ftype="i",fsize=0.8,lwd=1)
cols<-setNames(c("transparent",palette()[2]),c("non","pisc"))
par(lty="dotted",fg="transparent")
plot(sunfish.tree,cols,ftype="i",fsize=0.8,lwd=1,add=TRUE)
par(lty="solid",fg="black")
legend("topleft",c("non-piscivorous","piscivorous"),
  lwd=1,lty=c("solid","dotted"),col=palette()[c(4,2)],
  bty="n")

plot of chunk unnamed-chunk-14 Cool. That’s exactly what we were going for!

In the example below I’m going for the same concept, but with a fine grey outline & thicker lines. This takes a couple of additional steps, but the idea is the same.

These tree & data come from Esquerre et al. (2019).

library(phytools)
data("liolaemid.tree")
data("liolaemid.data")
head(liolaemid.data)
##                         parity_mode max_altitude temperature
## Ctenoblepharys_adspersa           O          750       23.05
## Liolaemus_abaucan                 O         2600       20.20
## Liolaemus_albiceps                V         4020       12.38
## Liolaemus_andinus                 V         4900       11.40
## Liolaemus_annectens               V         4688        5.10
## Liolaemus_anomalus                O         1400       23.78
parity<-setNames(liolaemid.data$parity_mode,
  rownames(liolaemid.data))
## create a stochastic character map of parity mode on a
## tree of liolaemid lizards
liolaemid_simmap<-make.simmap(liolaemid.tree,parity,
  model="ARD",pi="fitzjohn",nsim=1)
## make.simmap is sampling character histories conditioned on
## the transition matrix
## 
## Q =
##             O          V
## O -0.03670294 0.03670294
## V  0.00000000 0.00000000
## (estimated using likelihood);
## and (mean) root node prior probabilities
## pi =
## O V 
## 1 0
## Done.
## create the plot
plotTree(as.phylo(liolaemid_simmap), color="grey",type="arc",
  arc_height=0.2,part=1,fsize=0.5,lwd=4,ftype="i",offset=2)
par(fg="transparent")
plotTree(as.phylo(liolaemid_simmap),color="white",type="arc",
  arc_height=0.2,part=1,fsize=0.5,lwd=2,ftype="i",add=TRUE)
cols<-setNames(c("transparent","red"),levels(parity))
par(lty="dotted")
plot(liolaemid_simmap,cols,type="arc",arc_height=0.2,part=1,
  fsize=0.5,lwd=2,ftype="i",add=TRUE)
cols<-setNames(c("#20208D","transparent"),levels(parity))
par(lty="solid")
plot(liolaemid_simmap,cols,type="arc",arc_height=0.2,part=1,
  fsize=0.5,lwd=2,ftype="i",add=TRUE)
par(fg="black")
legend("topleft",c("oviparous","viviparous"),lty=c("solid","dotted"),
  col=c("#20208D","red"),lwd=3,bty="n")

plot of chunk unnamed-chunk-16