Monday, December 5, 2022

Re-coloring a contMap plot using the "viridis" color palette

I’m happy that the phytools function contMap (Revell 2013), for projecting a continuous trait onto the edges of a plotted tree using a color gradient, continues to be so popular nearly a decade after it was published.

One regret is the default color palette of the function. (In my defense, I am colorblind.) This color palette can easily be adjusted (using phytools::setMap), but all too often phylogenies are published using the default palette.

A good alternative palette that phytools users should consider is the “viridis” palette, which looks nice and is good for those with certain forms of colorblindness.

Let’s try it.

library(phytools)
data(mammal.tree)
mammal.tree
## 
## Phylogenetic tree with 49 tips and 48 internal nodes.
## 
## Tip labels:
##   U._maritimus, U._arctos, U._americanus, N._narica, P._lotor, M._mephitis, ...
## 
## Rooted; includes branch lengths.
data(mammal.data)
head(mammal.data)
##               bodyMass homeRange
## U._maritimus     265.0    115.60
## U._arctos        251.3     82.80
## U._americanus     93.4     56.80
## N._narica          4.4      1.05
## P._lotor           7.0      1.14
## M._mephitis        2.5      2.50
bodyMass<-setNames(mammal.data$bodyMass,
	rownames(mammal.data))
lnMass.cMap<-contMap(mammal.tree,log(bodyMass),
	plot=FALSE)

Firstly, here’s the default:

plot(lnMass.cMap,fsize=c(0.7,1),leg.txt="log(body mass)")

plot of chunk unnamed-chunk-2

Now, the “viridis” color palette. To get this, we’ll use the viridisLite CRAN package.

viridis.cMap<-setMap(lnMass.cMap,viridisLite::viridis(n=8))
plot(viridis.cMap,fsize=c(0.7,1),leg.txt="log(body mass)")

plot of chunk unnamed-chunk-3

This is (IMO) much nicer to look it. It also renders better in black & white, something we can see if we recolor it using TeachingDemos::col2grey as follows. (This requires that we modify the internals of our "contMap" object.)

grey.cMap<-viridis.cMap
grey.cMap$cols<-setNames(TeachingDemos::col2grey(viridis.cMap$cols),
	names(viridis.cMap$cols))
plot(grey.cMap,fsize=c(0.7,1),leg.txt="log(body mass)")

plot of chunk unnamed-chunk-4

Let’s compare that to when we simulate grey-scale printing on our original color gradient.

grey.cMap<-lnMass.cMap
grey.cMap$cols<-setNames(TeachingDemos::col2grey(lnMass.cMap$cols),
	names(lnMass.cMap$cols))
plot(grey.cMap,fsize=c(0.7,1),leg.txt="log(body mass)")

plot of chunk unnamed-chunk-5

Oh no! The highest & lowest values are actually converging! That’s probably about the worst behavior we could hope for.