YuLab-SMU / scatterpie

:art: scatter pie plot
https://cran.r-project.org/package=scatterpie
60 stars 16 forks source link

Adding scatterpie to a dendextend::ggdend phylogenetic tree #21

Open ndrubins opened 5 years ago

ndrubins commented 5 years ago

Hi,

I'm trying to plot a phylogenetic tree (in the form of a dendextend::ggdend object) along with scatterpie representing ancestral states in the internal nodes of the tree.

I'm running into a basic issue I was hoping you might be able to help out with.

Here is the phylogenetic species tree: species.tree <- ape::read.tree(text="(Platypus:0.1286194212,((((Koala:0.05906053125,Wallaby:0.06286946875):0.01269935535,Tasmanaian_devil:0.06666064465):0.002343400539,Opposum:0.07530014768):0.04236089288,((Armadillo:0.07766621875,Sloth:0.07828378125):0.02796723647,(((Rabbit:0.1031544407,(((Guinea_pig:0.07446361576,Chinchilla:0.07034397799):0.005464430664,(Naked_mole-rat:0.05677127221,Damarland_mole-rat:0.05767394654):0.01936294186):0.02759208881,(Jerboa:0.0947315755,(Blind_mole-rat:0.08812192941,((((Chinese_hamster:0.04926318023,Golden_hamster:0.05247866352):0.01638038784,Deer_mouse:0.06370916667):0.003237569002,Prairie_vole:0.07030201433):0.01060310787,(Rat:0.06290316531,Mouse:0.06094803666):0.01696014951):0.01220825015):0.009753667035):0.007422592018):0.004040214171):0.001369336039,(Mouse_lemur:0.07642478568,(Tarsier:0.07963153014,((Marmoset:0.03015044025,Mas_night_monkey:0.02517624473):0.02351744565,((((((Bonobo:0.00336025,Chimpanzee:0.00217975):0.004281320755,Human:0.006628679245):0.001853863546,Gorilla:0.008585696203):0.00845141498,Orangutan:0.01712893312):0.002774193206,Gibbon:0.01958316667):0.01096529033,(Green_monkey:0.01171472581,((Sooty_mangabey:0.006316729363,Baboon:0.006640801887):0.001116431826,(Macaque:0.003279600629,Pig-tailed_macaque:0.004228899371):0.004415690816):0.003992496416):0.01846812712):0.01778527361):0.02771818883):0.0005639189206):0.02209568299):0.0001,((European_hedgehog:0.1008965,Common_shrew:0.1078135):0.0009739982143,(Little_brown_bat:0.08947140351,((Cat:0.06468470992,(Dingo:0.00096371875,Dog:0.00134628125):0.06356096643):0.01565630777,((Dolphin:0.06816704487,(Pig:0.07646753755,((Goat:0.0113001875,Sheep:0.0110398125):0.01697194969,Cow:0.02692305031):0.05571845839):0.0001):0.01229828424,(Horse:0.00636975,Donkey:0.00667025):0.07594974567):0.004203855474):0.001715181365):0.01516209959):0.0001):0.0001):0.0145995455):0.006614758937);")

Now converting it into a dendextend::ggdend object:

library(ggplot2)
species.dend <- phylogram::as.dendrogram.phylo(species.tree) %>%
  dendextend::hang.dendrogram() %>%
  dendextend::hang.dendrogram(hang = -1) %>%
  dendextend::as.ggdend()

This: ggplot(species.dend,labels=F,horiz=T)+guides(fill=F)+coord_flip()+annotate("text",size=4.5,hjust=0,x=species.dend$label$x,y=species.dend$label$y,label=species.dend$label$label)+labs(x="",y="")+theme_minimal()+theme_void() plots species.dend horizontally.

Now I'm adding the ancestral state data - which is a data.frame with two ancestral states for each internal node in the tree (state0 and state1), each with probability between 0 and 1:

species <- species.tree$tip.label
ancestral.state.df <- species.dend$nodes %>%
  dplyr::filter(is.na(leaf)) %>%
  dplyr::select(x,y,cex,members) %>%
  dplyr::mutate(node.idx = members+length(species)-1) %>%
  dplyr::select(x,y,node.idx) %>%
  dplyr::left_join(data.frame(node.idx=as.numeric(c(95,94,51,50,49,90,49,88,75,60,59,51,49,49,55,54,53,51,50,49,49,62,61,60,49,58,53,52,51,50,49,52,51,49,49,60,49,58,57,50,49,54,52,51,50,49,49)),
                              state0=c(0,0,1,1,1,0.5,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1),
                              state1=c(1,1,0,0,0,0.5,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0),stringsAsFactors = F),by=c("node.idx"="node.idx")) %>%
  unique()

And now I would like to plot species.dend along with the ancestral states mapped to their ancestral node xy coordinates as specified by ancestral.state.df. I thought this should work:

library(scatterpie)
ggplot(species.dend,labels=F,horiz=T)+guides(fill=F)+coord_flip()+annotate("text",size=4.5,hjust=0,x=species.dend$label$x,y=species.dend$label$y,label=species.dend$label$label)+labs(x="",y="")+theme_minimal()+theme_void()+
  geom_scatterpie(aes(x=y,y=x,r=0.3),data=ancestral.state.df,cols=c("state0","state1"))+
  coord_equal()+labs(x="",y="",fill="Ancestral State")+
  theme_minimal()+theme_void()

But unfortunately it comes out poorly.

Any idea how to get the ancestral states as pie charts located at the xy coordinates of the ancestral nodes in species.dend?