--- title: "ggtreeExtra" author: | | Shuangbin Xu and GuangChuang Yu | School of Basic Medical Sciences, Southern Medical University date: "`r Sys.Date()`" bibliography: ggtreeExtra.bib biblio-style: apalike output: prettydoc::html_pretty: toc: true theme: cayman highlight: vignette pdf_document: toc: true vignette: > %\VignetteIndexEntry{ggtreeExtra} %\VignetteEngine{knitr::rmarkdown} %\usepackage[utf8]{inputenc} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE, results="asis", message=FALSE, KnitrSetUp} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) Biocpkg <- function (pkg){ sprintf("[%s](http://bioconductor.org/packages/%s)", pkg, pkg) } CRANpkg <- function(pkg){ cran <- "https://CRAN.R-project.org/package" fmt <- "[%s](%s=%s)" sprintf(fmt, pkg, cran, pkg) } ``` # Setup ```{r, message=FALSE, setup} library(ggtreeExtra) library(ggstar) library(ggplot2) library(ggtree) library(treeio) library(ggnewscale) ``` # 1. Introduction The `geom_facet` function provided in the `r Biocpkg("ggtree")` package [@yu2017ggtree] was designed to align associated graphs to the tree [@yu2018two]. It only works with `rectangular`, `roundrect`, `ellipse` and `slanted` layouts to present tree data on external panels. To extend `r Biocpkg("ggtree")` to present associated data on the outer rings of phylogenetic tree in `circular`, `fan` and `radial` layouts, we developed `r Biocpkg("ggtreeExtra")`, which is able to align associated graphs with a tree in `rectangular`, `circular`, `fan` and `radial` layouts. The `ggtreeExtra` package provides a function, `geom_fruit`, to align graphs to a tree. The associated graphs will align at different positions of the external panels of the tree. We also developed `geom_fruit_list` to add multiple layers at the same external panel of tree. Furthermore, `axis` of an external layer can be added using the `axis.params=list(axis="x",...)` in `geom_fruit`. Background grid lines of an external layer can be added using the `grid.params=list()` in `geom_fruit`. These functions are based on `r CRANpkg("ggplot2")` and support using grammar of graphics [@hadlyggplot2]. See also [Chapter10](https://yulab-smu.top/treedata-book/chapter10.html) of the [online book](http://yulab-smu.top/treedata-book). # 2. Install You can use the following commands to install it ```{r, eval=FALSE, INSTALL} # for devel if(!requireNamespace("remotes", quietly=TRUE)){ install.packages("remotes") } remotes::install_github("YuLab-SMU/ggtreeExtra") # for release if (!requireNamespace("BiocManager", quietly=TRUE)) install.packages("BiocManager") ## BiocManager::install("BiocUpgrade") ## you may need this BiocManager::install("ggtreeExtra") ``` # 3. Usage To demonstrate the usages of the package, we use a tree file downloaded from [plotTree](https://github.com/katholt/plotTree/blob/master/tree_example_april2015/tree.nwk) with simulated associated datasets. All the simulated datasets contain one column of taxa labels of the tree. ## 3.1 add single layer ```{r, fig.align="center", fig.height=7, fig.width=7, warning=FALSE, singlelayer} # The path of tree file. trfile <- system.file("extdata", "tree.nwk", package="ggtreeExtra") # The path of file to plot tip point. tippoint1 <- system.file("extdata", "tree_tippoint_bar.csv", package="ggtreeExtra") # The path of first layer outside of tree. ring1 <- system.file("extdata", "first_ring_discrete.csv", package="ggtreeExtra") # The path of second layer outside of tree. ring2 <- system.file("extdata", "second_ring_continuous.csv", package="ggtreeExtra") # The tree file was imported using read.tree. If you have other tree format files, you can use corresponding functions from treeio package to read it. tree <- read.tree(trfile) # This dataset will to be plotted point and bar. dat1 <- read.csv(tippoint1) knitr::kable(head(dat1)) # This dataset will to be plotted heatmap dat2 <- read.csv(ring1) knitr::kable(head(dat2)) # This dataset will to be plotted heatmap dat3 <- read.csv(ring2) knitr::kable(head(dat3)) # The format of the datasets is the long shape for ggplot2. If you have short shape dataset, # you can use `melt` of `reshape2` or `pivot_longer` of `tidyr` to convert it. # We use ggtree to create fan layout tree. p <- ggtree(tree, layout="fan", open.angle=10, size=0.5) p ## Next, we can use %<+% of ggtree to add annotation dataset to tree. #p1 <- p %<+% dat1 #p1 ## We use geom_star to add point layer outside of tree. #p2 <- p1 + # geom_star( # mapping=aes(fill=Location, size=Length, starshape=Group), # starstroke=0.2 # ) + # scale_size_continuous( # range=c(1, 3), # guide=guide_legend( # keywidth=0.5, # keyheight=0.5, # override.aes=list(starshape=15), # order=2) # ) + # scale_fill_manual( # values=c("#F8766D", "#C49A00", "#53B400", "#00C094", "#00B6EB", "#A58AFF", "#FB61D7"), # guide="none" # don't show the legend. # ) + # scale_starshape_manual( # values=c(1, 15), # guide=guide_legend( # keywidth=0.5, # adjust width of legend # keyheight=0.5, # adjust height of legend # order=1 # adjust the order of legend for multiple legends. # ), # na.translate=FALSE # to remove the NA legend. # ) #p2 # Or if you don't use %<+% to import annotation dataset, instead of `data` parameter of `geom_fruit`. # You should specify the column contained tip labels to y axis of `mapping`, here is `y=ID`. # the `position` parameter was set to `identity` to add the points on the tip nodes. p2 <- p + geom_fruit( data=dat1, geom=geom_star, mapping=aes(y=ID, fill=Location, size=Length, starshape=Group), position="identity", starstroke=0.2 ) + scale_size_continuous( range=c(1, 3), # the range of size. guide=guide_legend( keywidth=0.5, keyheight=0.5, override.aes=list(starshape=15), order=2 ) ) + scale_fill_manual( values=c("#F8766D", "#C49A00", "#53B400", "#00C094", "#00B6EB", "#A58AFF", "#FB61D7"), guide="none" ) + scale_starshape_manual( values=c(1, 15), guide=guide_legend( keywidth=0.5, keyheight=0.5, order=1 ) ) p2 # Next, we will add a heatmap layer on the outer ring of p2 using `geom_tile` of `ggplot2`. # Since we want to map some variable of dataset to the `fill` aesthetics of `geom_tile`, but # the `fill` of p2 had been mapped. So I need use `new_scale_fill` of `ggnewscale` package to initialize it. p3 <- p2 + new_scale_fill() + geom_fruit( data=dat2, geom=geom_tile, mapping=aes(y=ID, x=Pos, fill=Type), offset=0.08, # The distance between external layers, default is 0.03 times of x range of tree. pwidth=0.25 # width of the external layer, default is 0.2 times of x range of tree. ) + scale_fill_manual( values=c("#339933", "#dfac03"), guide=guide_legend(keywidth=0.5, keyheight=0.5, order=3) ) p3 # You can also add heatmap layer for continuous values. p4 <- p3 + new_scale_fill() + geom_fruit( data=dat3, geom=geom_tile, mapping=aes(y=ID, x=Type2, alpha=Alpha, fill=Type2), pwidth=0.15, axis.params=list( axis="x", # add axis text of the layer. text.angle=-45, # the text angle of x-axis. hjust=0 # adjust the horizontal position of text of axis. ) ) + scale_fill_manual( values=c("#b22222", "#005500", "#0000be", "#9f1f9f"), guide=guide_legend(keywidth=0.5, keyheight=0.5, order=4) ) + scale_alpha_continuous( range=c(0, 0.4), # the range of alpha guide=guide_legend(keywidth=0.5, keyheight=0.5, order=5) ) # Then add a bar layer outside of the tree. p5 <- p4 + new_scale_fill() + geom_fruit( data=dat1, geom=geom_col, mapping=aes(y=ID, x=Abundance, fill=Location), #The 'Abundance' of 'dat1' will be mapped to x pwidth=0.4, axis.params=list( axis="x", # add axis text of the layer. text.angle=-45, # the text size of axis. hjust=0 # adjust the horizontal position of text of axis. ), grid.params=list() # add the grid line of the external bar plot. ) + scale_fill_manual( values=c("#F8766D", "#C49A00", "#53B400", "#00C094", "#00B6EB", "#A58AFF", "#FB61D7"), guide=guide_legend(keywidth=0.5, keyheight=0.5, order=6) ) + theme(#legend.position=c(0.96, 0.5), # the position of legend. legend.background=element_rect(fill=NA), # the background of legend. legend.title=element_text(size=7), # the title size of legend. legend.text=element_text(size=6), # the text size of legend. legend.spacing.y = unit(0.02, "cm") # the distance of legends (y orientation). ) p5 ``` ## 3.2 add multiple layers on the same position. In the section, we simulated a tree with several associated datasets, and used `geom_fruit_list` to add multiple layers at the same external panel of the tree. ```{r, fig.align="center", fig.width=7, fig.width=7, multilayer} # To reproduce. set.seed(1024) # generate a tree contained 100 tip labels. tr <- rtree(100) # generate three datasets, which are the same except the third column name. dt <- data.frame(id=tr$tip.label, value=abs(rnorm(100)), group=c(rep("A",50),rep("B",50))) df <- dt dtf <- dt colnames(df)[[3]] <- "group2" colnames(dtf)[[3]] <- "group3" # plot tree p <- ggtree(tr, layout="fan", open.angle=0) p # the first ring. p1 <- p + geom_fruit( data = dt, geom = geom_col, mapping = aes(y=id, x=value, fill=group), ) + new_scale_fill() p1 # the second ring # geom_fruit_list is a list, which first element must be layer of geom_fruit. p2 <- p1 + geom_fruit_list( geom_fruit( data = df, geom = geom_col, mapping = aes(y=id, x=value, fill=group2), ), scale_fill_manual(values=c("blue", "red")), # To map group2 new_scale_fill(), # To initialize fill scale. geom_fruit( data = dt, geom = geom_star, mapping = aes(y=id, x=value, fill=group), size = 2.5, color = NA, starstroke = 0 ) ) + new_scale_fill() p2 # The third ring p3 <- p2 + geom_fruit( data = dtf, geom = geom_col, mapping = aes(y=id, x=value, fill=group3), stat = "identity" ) + scale_fill_manual(values=c("#00AED7", "#009E73")) p3 ``` # 4. Need helps? If you have any questions/issues, please visit [github issue tracker](https://github.com/YuLab-SMU/ggtreeExtra/issues). You also can post to [google group](https://groups.google.com/forum/#!forum/bioc-ggtree). Users are highly recommended to subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bioc-ggtree). # 5. Session information Here is the output of sessionInfo() on the system on which this document was compiled: ```{r, echo=FALSE} sessionInfo() ``` # 6. Reference