ixxmu / mp_duty

抓取网络文章到github issues保存
https://archives.duty-machine.now.sh/
112 stars 30 forks source link

用ggtreeExtra给进化树加热图 #1092

Closed ixxmu closed 3 years ago

ixxmu commented 3 years ago

https://mp.weixin.qq.com/s/1tykulMweydz3zdH8ZXTyA

github-actions[bot] commented 3 years ago

用ggtreeExtra给进化树加热图 by 作图丫

答案肯定是可以的,而且有很多种方法都可以实现。这图的比较特别之处就是外圈的热图较为少见,但其实熟悉ggplot2的用户就知道无非就是用了两层的热图相叠加即可。而ggplot2提供的geom_tile图层就可以画热图了,当然只要变通下用点图也是可以的,点图层就可以用ggplot2geom_point或者ggstargeom_star。对于如何将树与这些图层对齐组合在一起,用ggtreeExtrageom_fruit或者ggtreegeom_facet就可以实现了。这两个图层可以将ggplot的图层跟ggtree连接起来。

模拟数据

一下数据均来自模拟。由于ggtree与ggtreeExtra的设计理念与ggplot2是相似的,所以要用这些图层的时候,数据格式也只需要根据相应图层的数据格式来准备即可。

set.seed(123)
n <- 50
tr <- treeio::rtree(n)

dat1 <- data.frame(
           id=rep(tr$tip.label, 8),
           sample=c(rep(c("A1","A2""A3""A4"), each=n),
                    rep(c("B1""B2""B3""B4"), each=n)),
           group=c(rep("A", n * 4), rep("B", n * 4)),
           subgroup=rep("T", n*8)
       )

dat1[sample(nrow(dat1), 0.75 * n * 8), "subgroup"] <- NA
dat1$subgroup <- ifelse(!is.na(dat1$subgroup), dat1$group, NA)

df <- data.frame(
           id = tr$tip.label[sample(n, 10)],
           tipgroup = c(rep("a"3), rep("b"3), rep("c"4))
      )

进化树图层与tiplab图层

左边的进化树很简单,用ggtree即可,tip label只需要加一层geom_tiplab图层即可。为了方便后续的操作,这里将geom_tiplab赋值给tiplab。

library(ggtree)
## ggtree v3.1.1  For help: https://yulab-smu.top/treedata-book/
##
## If you use ggtree in published research, please cite the most appropriate paper(s):
##
## 1. Guangchuang Yu. Using ggtree to visualize data on tree-like structures. Current Protocols in Bioinformatics, 2020, 69:e96. doi:10.1002/cpbi.96
## 2. Guangchuang Yu, Tommy Tsan-Yuk Lam, Huachen Zhu, Yi Guan. Two methods for mapping and visualizing associated data on phylogeny using ggtree. Molecular Biology and Evolution 2018, 35(12):3041-3043. doi:10.1093/molbev/msy194
## 3. Guangchuang Yu, David Smith, Huachen Zhu, Yi Guan, Tommy Tsan-Yuk Lam. ggtree: an R package for visualization and annotation of phylogenetic trees with their covariates and other associated data. Methods in Ecology and Evolution 2017, 8(1):28-36. doi:10.1111/2041-210X.12628
p <- ggtree(tr)

tiplab <- geom_tiplab(align = TRUE)

tiplab图层的高亮与点热图

进化树的tiplab颜色也有很多种方法可以实现,比如在前面一小节构建的geom_tiplab中用geom_tiplab(geom="label",fill=yourcolor)就可以。当然也可以用热图图层geom_tile来实现。比如这个小节的gftile就是。而对于点热图无非就是叠加了两层点图层,但是ggtreeExtra提供的geom_fruit默认是错开而不是叠加在一起的。所以我们又提供了geom_fruit_list,这个功能可以将这些外部的图层在同一个位置上展示。只需要将这些图层都放在一起就可以,fg对象就是叠加后的。

library(ggtreeExtra)
## ggtreeExtra v1.3.0.990  For help: https://yulab-smu.top/treedata-book/
##
## If you use ggtreeExtra in published research, please cite the paper:
##
## SB Xu, Z Dai, P Guo, X Fu, S Liu, L Zhou, W Tang, T Feng, M Chen, L Zhan, T Wu, E Hu, G Yu. ggtreeExtra: Compact visualization of richly annotated phylogenetic data. Research Square. doi: 10.21203/rs.3.rs-155672/v2, (preprint).
library(ggstar)
library(ggplot2)
gftile <- geom_fruit(
              data=df,
              geom=geom_tile,
              mapping=aes(y=id, fill=tipgroup),
              offset = 0.05,
              width = 0.5
          )

gf1 <- geom_fruit(
           data=dat1,
           geom=geom_star,
           mapping=aes(x=sample, y=id, color=group),
           size = 3,
           starshape=15,
           offset=0.04,
           pwidth=0.25
           )

gf2 <- geom_fruit(
           data=dat1,
           geom=geom_star,
           mapping=aes(x=sample, y=id, fill=subgroup),
           size = 3,
           starstroke=0,
           starshape = 15,
           offset=0.04,
           pwidth=0.25,
           axis.params = list(axis="x", text.size=3, vjust=1, line.size=0, text.angle=-45, hjust=0)
       )

linecolor <- scale_color_manual(values=c("#00AED7""#009E73"))
fillcolor <- scale_fill_manual(values=c("#00AED7""#009E73"), na.translate = FALSE)

fg <- geom_fruit_list(gf2, gf1, linecolor, fillcolor)

组装结果

有了上面构建的这些图层对象元件,用+进行组装即可。有两个注意点:+为了不让tiplab的高亮图层将label挡住,就可以将gftile(高亮的图层)放到tiplab(tip label图层)前。+gftile图层中已经用了fill标尺,而后面的点图层也需要用fill标尺,所以在其后面需要用ggnewscalenew_scale("fill")来进行初始化。

library(ggplot2)
library(ggnewscale)
p1 <- p + 
      geom_treescale(y=-0.5) +
      gftile +
      scale_fill_manual(values=c("#66C2A5""#FC8D62""#8DA0CB")) + 
      new_scale("fill") +
      tiplab +
      fg + 
      scale_y_continuous(limits=c(-1NA))
## Scale for 'y' is already present. Adding another scale for 'y', which will
## replace the existing scale.
p1

总结

ggtreeggtreeExtra的语法都是与ggplot2相似的,可以说只要会了ggplot2也就基本会了ggtreeggtreeExtra。如果熟悉了ggtreeggtreeExtra,那对ggplot2的熟悉程度也将进一步加深。