Browse code

unrooted layout

guangchuang yu authored on 21/12/2017 12:07:05
Showing12 changed files

... ...
@@ -2,7 +2,7 @@ Package: ggtree
2 2
 Type: Package
3 3
 Title: an R package for visualization and annotation of phylogenetic trees with
4 4
     their covariates and other associated data
5
-Version: 1.11.3
5
+Version: 1.11.4
6 6
 Authors@R: c(
7 7
 	   person("Guangchuang", "Yu",     email = "guangchuangyu@gmail.com", role = c("aut", "cre", "cph"), comment = c(ORCID = "0000-0002-6485-8781")),
8 8
 	   person("Tommy Tsan-Yuk", "Lam", email = "tylam.tommy@gmail.com",   role = c("aut", "ths")),
9 9
new file mode 100644
... ...
@@ -0,0 +1,6 @@
1
+# ggtree 1.11.4
2
+
3
++ update vignette (2017-12-21, Thu)
4
+    - remove ggtreeUtilities.Rmd
5
+    - merge treeAnnotation and advanceTreeAnnotation
6
+    
0 7
\ No newline at end of file
... ...
@@ -165,54 +165,54 @@ scaleY <- function(phylo, df, yscale, layout, ...) {
165 165
 ## }
166 166
 
167 167
 
168
-## used by layoutEqualAngle
169
-## will change to tidytree::as_data_frame in future
170
-as.data.frame.phylo_ <- function(x, layout="rectangular",
171
-                                 branch.length="branch.length", ...) {
172
-    if (branch.length != 'none') {
173
-        branch.length = "branch.length"
174
-    }
175
-    tip.label <- x[["tip.label"]]
176
-    Ntip <- length(tip.label)
177
-    N <- getNodeNum(x)
178
-    edge <- as.data.frame(x[["edge"]])
179
-    colnames(edge) <- c("parent", "node")
180
-    if (! is.null(x$edge.length)) {
181
-        edge$length <- x$edge.length
182
-        if (branch.length == "none") {
183
-            xpos <- getXcoord_no_length(x)
184
-            ypos <- getYcoord(x)
185
-        } else {
186
-            xpos <- getXcoord(x)
187
-            ypos <- getYcoord(x)
188
-        }
189
-        ## } else  if (layout != "cladogram") {
190
-        ##     xpos <- getXcoord(x)
191
-        ##     ypos <- getYcoord(x)
192
-        ## } else {
193
-        ##     ## layout == "cladogram" && branch.length != "none"
194
-        ##     xy <- getXYcoord_cladogram(x)
195
-        ##     xpos <- xy$x
196
-        ##     ypos <- xy$y
197
-        ## }
198
-    } else {
199
-        xpos <- getXcoord_no_length(x)
200
-        ypos <- getYcoord(x)
201
-    }
202
-    xypos <- data.frame(node=1:N, x=xpos, y=ypos)
203
-    res <- merge(edge, xypos, by.x="node", by.y="node", all.y=TRUE)
204
-    label <- rep(NA, N)
205
-    label[1:Ntip] <- tip.label
206
-    if ( !is.null(x$node.label) ) {
207
-        label[(Ntip+1):N] <- x$node.label
208
-    }
209
-    res$label <- label
210
-    isTip <- rep(FALSE, N)
211
-    isTip[1:Ntip] <- TRUE
212
-    res$isTip <- isTip
213
-    ## add branch mid position
214
-    res <- calculate_branch_mid(res)
215
-    ## ## angle for all layout, if 'rectangular', user use coord_polar, can still use angle
216
-    res <- calculate_angle(res)
217
-    return(res)
218
-}
168
+## ## used by layoutEqualAngle
169
+## ## will change to tidytree::as_data_frame in future
170
+## as.data.frame.phylo_ <- function(x, layout="rectangular",
171
+##                                  branch.length="branch.length", ...) {
172
+##     if (branch.length != 'none') {
173
+##         branch.length = "branch.length"
174
+##     }
175
+##     tip.label <- x[["tip.label"]]
176
+##     Ntip <- length(tip.label)
177
+##     N <- getNodeNum(x)
178
+##     edge <- as.data.frame(x[["edge"]])
179
+##     colnames(edge) <- c("parent", "node")
180
+##     if (! is.null(x$edge.length)) {
181
+##         edge$length <- x$edge.length
182
+##         if (branch.length == "none") {
183
+##             xpos <- getXcoord_no_length(x)
184
+##             ypos <- getYcoord(x)
185
+##         } else {
186
+##             xpos <- getXcoord(x)
187
+##             ypos <- getYcoord(x)
188
+##         }
189
+##         ## } else  if (layout != "cladogram") {
190
+##         ##     xpos <- getXcoord(x)
191
+##         ##     ypos <- getYcoord(x)
192
+##         ## } else {
193
+##         ##     ## layout == "cladogram" && branch.length != "none"
194
+##         ##     xy <- getXYcoord_cladogram(x)
195
+##         ##     xpos <- xy$x
196
+##         ##     ypos <- xy$y
197
+##         ## }
198
+##     } else {
199
+##         xpos <- getXcoord_no_length(x)
200
+##         ypos <- getYcoord(x)
201
+##     }
202
+##     xypos <- data.frame(node=1:N, x=xpos, y=ypos)
203
+##     res <- merge(edge, xypos, by.x="node", by.y="node", all.y=TRUE)
204
+##     label <- rep(NA, N)
205
+##     label[1:Ntip] <- tip.label
206
+##     if ( !is.null(x$node.label) ) {
207
+##         label[(Ntip+1):N] <- x$node.label
208
+##     }
209
+##     res$label <- label
210
+##     isTip <- rep(FALSE, N)
211
+##     isTip[1:Ntip] <- TRUE
212
+##     res$isTip <- isTip
213
+##     ## add branch mid position
214
+##     res <- calculate_branch_mid(res)
215
+##     ## ## angle for all layout, if 'rectangular', user use coord_polar, can still use angle
216
+##     res <- calculate_angle(res)
217
+##     return(res)
218
+## }
... ...
@@ -49,10 +49,6 @@ ggtree <- function(tr,
49 49
         message('"daylight" method was used as default layout for unrooted tree.')
50 50
     }
51 51
 
52
-    if (is(tr, "r8s") && branch.length == "branch.length") {
53
-        branch.length = "TREE"
54
-    }
55
-
56 52
     if(yscale != "none") {
57 53
         ## for 2d tree
58 54
         layout <- "slanted"
... ...
@@ -29,20 +29,24 @@ fortify.phylo <- function(model, data,
29 29
         }
30 30
     }
31 31
 
32
-    if (is.null(x$edge.length) || branch.length == "none") {
33
-        xpos <- getXcoord_no_length(x)
32
+    if (layout %in% c("equal_angle", "daylight")) {
33
+        res <- layout.unrooted(x, layout.method = layout, branch.length = branch.length, ...)
34 34
     } else {
35
-        xpos <- getXcoord(x)
36
-    }
35
+        if (is.null(x$edge.length) || branch.length == "none") {
36
+            xpos <- getXcoord_no_length(x)
37
+        } else {
38
+            xpos <- getXcoord(x)
39
+        }
37 40
 
38
-    ypos <- getYcoord(x)
39
-    N <- Nnode(x, internal.only=FALSE)
40
-    xypos <- data_frame(node=1:N, x=xpos, y=ypos)
41
+        ypos <- getYcoord(x)
42
+        N <- Nnode(x, internal.only=FALSE)
43
+        xypos <- data_frame(node=1:N, x=xpos, y=ypos)
41 44
 
42
-    df <- as_data_frame(model) %>%
43
-        mutate_(isTip = ~(! node %in% parent))
45
+        df <- as_data_frame(model) %>%
46
+            mutate_(isTip = ~(! node %in% parent))
44 47
 
45
-    res <- full_join(df, xypos, by = "node")
48
+        res <- full_join(df, xypos, by = "node")
49
+    }
46 50
 
47 51
     ## add branch mid position
48 52
     res <- calculate_branch_mid(res)
... ...
@@ -1,12 +1,5 @@
1 1
 
2 2
 
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10 3
 ##' @importFrom ape reorder.phylo
11 4
 layout.unrooted <- function(tree, branch.length="branch.length", layout.method="equal_angle", ...) {
12 5
 
... ...
@@ -18,6 +11,21 @@ layout.unrooted <- function(tree, branch.length="branch.length", layout.method="
18 11
     return(df)
19 12
 }
20 13
 
14
+set_branch_length_cladogram <- function(tree) {
15
+    phylo <- as.phylo(tree)
16
+    edge <- phylo$edge
17
+    xpos <- getXcoord_no_length(phylo)
18
+    phylo$edge.length <- xpos[edge[,2]] - xpos[edge[,1]]
19
+
20
+    if (is(tree, "phylo")) {
21
+        return(phylo)
22
+    } else if (is(tree, "treedata")) {
23
+        tree@phylo <- phylo
24
+        return(tree)
25
+    }
26
+    message("unknown tree object, fail to set branch length for cladogram...")
27
+    return(tree)
28
+}
21 29
 
22 30
 ##' 'Equal-angle layout algorithm for unrooted trees'
23 31
 ##'
... ...
@@ -29,9 +37,15 @@ layout.unrooted <- function(tree, branch.length="branch.length", layout.method="
29 37
 ##' @param branch.length set to 'none' for edge length of 1. Otherwise the phylogenetic tree edge length is used.
30 38
 ##' @return tree as data.frame with equal angle layout.
31 39
 layoutEqualAngle <- function(tree, branch.length ){
40
+    if (branch.length == "none") {
41
+        tree <- set_branch_length_cladogram(tree)
42
+    }
43
+
32 44
     root <- getRoot(tree)
33 45
     ## Convert Phylo tree to data.frame.
34
-    df <- as.data.frame.phylo_(tree)
46
+    ## df <- as.data.frame.phylo_(tree)
47
+    df <- as_data_frame(tree) %>%
48
+        mutate_(isTip = ~(! node %in% parent))
35 49
 
36 50
     ## NOTE: Angles (start, end, angle) are in half-rotation units (radians/pi or degrees/180)
37 51
 
... ...
@@ -82,11 +96,11 @@ layoutEqualAngle <- function(tree, branch.length ){
82 96
             ## beta = angle of line from parent node to i-th child.
83 97
             beta <- start + alpha / 2
84 98
 
85
-            if (branch.length == "none") {
86
-                length.child <- 1
87
-            } else {
88
-                length.child <- df[child, "length"]
89
-            }
99
+            ## if (branch.length == "none") {
100
+            ##     length.child <- 1
101
+            ## } else {
102
+            length.child <- df[child, "branch.length"]
103
+            ##}
90 104
 
91 105
             ## update geometry of data.frame.
92 106
             ## Calculate (x,y) position of the i-th child node from current node.
... ...
@@ -169,7 +183,7 @@ layoutDaylight <- function( tree, branch.length ){
169 183
         # Calculate the running average of angle changes.
170 184
         ave_change <- total_max / length(nodes) * length(i)
171 185
 
172
-        cat('Average angle change [',i,']', ave_change,'\n')
186
+        message('Average angle change [',i,'] ', ave_change)
173 187
 
174 188
         i <- i + 1
175 189
     }
... ...
@@ -237,19 +251,19 @@ applyLayoutDaylight <- function(df, node_id){
237 251
   # Find start and end angles for each subtree.
238 252
   #   subtrees = get subtrees of node
239 253
   #   for i-th subtree in subtrees {
240
-  for (i in seq_along(subtrees) ) {
241
-    subtree <- subtrees[[i]]
242
-    # [end, start] = get start and end angles of tree.
243
-
244
-    angles <- getTreeArcAngles(df, node_id, subtree)
245
-    angle_list[ i, 'subtree_id'] <- i
246
-    angle_list[ i, 'left'] <- angles['left']
247
-    angle_list[ i, 'beta'] <- angles['left'] - angles['right'] # subtree arc angle
248
-    # If subtree arc angle is -ve, then + 2 (360).
249
-    if(angle_list[ i, 'beta'] < 0 ){
250
-      angle_list[ i, 'beta'] <- angle_list[ i, 'beta'] + 2
254
+    for (i in seq_along(subtrees) ) {
255
+        subtree <- subtrees[[i]]
256
+                                        # [end, start] = get start and end angles of tree.
257
+
258
+        angles <- getTreeArcAngles(df, node_id, subtree)
259
+        angle_list[ i, 'subtree_id'] <- i
260
+        angle_list[ i, 'left'] <- angles['left']
261
+        angle_list[ i, 'beta'] <- angles['left'] - angles['right'] # subtree arc angle
262
+                                        # If subtree arc angle is -ve, then + 2 (360).
263
+        if(angle_list[ i, 'beta'] < 0 ){
264
+            angle_list[ i, 'beta'] <- angle_list[ i, 'beta'] + 2
265
+        }
251 266
     }
252
-  }
253 267
   #   sort angle_list by 'left angle' column in ascending order.
254 268
   angle_list <- angle_list[with(angle_list, order(left)), ]
255 269
   #   D = 360 - sum( angle_list['beta'] ) # total day
... ...
@@ -293,59 +307,59 @@ applyLayoutDaylight <- function(df, node_id){
293 307
 ##' @param subtree named list of root id of subtree (node) and list of node ids for given subtree (subtree).
294 308
 ##' @return named list with right and left angles in range [0,2] i.e 1 = 180 degrees, 1.5 = 270 degrees.
295 309
 getTreeArcAngles <- function(df, origin_id, subtree) {
296
-  # Initialise variables
297
-  theta_child <- 0.0
298
-  subtree_root_id <- subtree$node
299
-  subtree_node_ids <- subtree$subtree
300
-
301
-  # Initialise angle from origin node to parent node.
302
-  # If subtree_root_id is child of origin_id
303
-  if( any(subtree_root_id == getChild.df(df, origin_id)) ){
304
-    # get angle from original node to parent of subtree.
305
-    theta_left <- getNodeAngle.df(df, origin_id, subtree_root_id)
306
-    theta_right <- theta_left
307
-  }else if( subtree_root_id == origin_id){
308
-    # Special case.
309
-    # get angle from parent of subtree to children
310
-    children_ids <- getChild.df(df, subtree_root_id)
311
-
312
-    if(length(children_ids) == 2){
313
-      # get angles from parent to it's two children.
314
-      theta1 <- getNodeAngle.df(df, origin_id, children_ids[1])
315
-      theta2 <- getNodeAngle.df(df, origin_id, children_ids[2])
316
-
317
-      delta <- theta1 - theta2
318
-
319
-
320
-      # correct delta for points crossing 180/-180 quadrant.
321
-      if(delta > 1){
322
-        delta_adj = delta - 2
323
-      }else if(delta < -1){
324
-        delta_adj = delta + 2
325
-      }else{
326
-        delta_adj <- delta
327
-      }
310
+    ## Initialise variables
311
+    theta_child <- 0.0
312
+    subtree_root_id <- subtree$node
313
+    subtree_node_ids <- subtree$subtree
314
+
315
+    ## Initialise angle from origin node to parent node.
316
+    ## If subtree_root_id is child of origin_id
317
+    if( any(subtree_root_id == getChild.df(df, origin_id)) ){
318
+        ## get angle from original node to parent of subtree.
319
+        theta_left <- getNodeAngle.df(df, origin_id, subtree_root_id)
320
+        theta_right <- theta_left
321
+    } else if( subtree_root_id == origin_id ){
322
+        ## Special case.
323
+        ## get angle from parent of subtree to children
324
+        children_ids <- getChild.df(df, subtree_root_id)
325
+
326
+        if(length(children_ids) == 2){
327
+            ## get angles from parent to it's two children.
328
+            theta1 <- getNodeAngle.df(df, origin_id, children_ids[1])
329
+            theta2 <- getNodeAngle.df(df, origin_id, children_ids[2])
330
+
331
+            delta <- theta1 - theta2
332
+
333
+
334
+            ## correct delta for points crossing 180/-180 quadrant.
335
+            if(delta > 1){
336
+                delta_adj = delta - 2
337
+            } else if(delta < -1){
338
+                delta_adj = delta + 2
339
+            } else{
340
+                delta_adj <- delta
341
+            }
328 342
 
329
-      if(delta_adj >= 0){
330
-        theta_left = theta1
331
-        theta_right = theta2
332
-      }else if(delta_adj < 0){
333
-        theta_left = theta2
334
-        theta_right = theta1
335
-      }
336
-    }else{
337
-      # subtree only has one child node.
338
-      theta_left <- getNodeAngle.df(df, origin_id, children_ids[1])
339
-      theta_right <- theta_left
340
-    }
343
+            if(delta_adj >= 0){
344
+                theta_left = theta1
345
+                theta_right = theta2
346
+            } else if(delta_adj < 0){
347
+                theta_left = theta2
348
+                theta_right = theta1
349
+            }
350
+        }else{
351
+            ## subtree only has one child node.
352
+            theta_left <- getNodeAngle.df(df, origin_id, children_ids[1])
353
+            theta_right <- theta_left
354
+        }
341 355
 
342
-  }else{
343
-    # get the real root of df tree to initialise left and right angles.
344
-    tree_root <- getRoot.df(df)
345
-    if( !is.na(tree_root) & is.numeric(tree_root) ){
346
-      theta_left <- getNodeAngle.df(df, origin_id, tree_root)
347
-      theta_right <- theta_left
348
-    }else{
356
+    } else {
357
+        ## get the real root of df tree to initialise left and right angles.
358
+        tree_root <- getRoot.df(df)
359
+        if( !is.na(tree_root) & is.numeric(tree_root) ){
360
+            theta_left <- getNodeAngle.df(df, origin_id, tree_root)
361
+            theta_right <- theta_left
362
+        } else{
349 363
       print('ERROR: no root found!')
350 364
       theta_left <- NA
351 365
     }
... ...
@@ -526,8 +540,8 @@ rotateTreePoints.df <- function(df, pivot_node, nodes, angle){
526 540
 ##' @return angle in range [-1, 1], i.e. degrees/180, radians/pi
527 541
 getNodeAngle.df <- function(df, origin_node_id, node_id){
528 542
   if( (origin_node_id != node_id) & any(origin_node_id %in% df$node) & any(node_id %in% df$node) ){
529
-    delta_x <- df[node_id, 'x'] - df[origin_node_id, 'x']
530
-    delta_y <- df[node_id, 'y'] - df[origin_node_id, 'y']
543
+    delta_x <- df$x[node_id] - df$x[origin_node_id]
544
+    delta_y <- df$y[node_id] - df$y[origin_node_id]
531 545
     angle <- atan2(delta_y, delta_x) / pi
532 546
     return( angle )
533 547
   }else{
... ...
@@ -681,8 +695,9 @@ getRoot.df <- function(df, node){
681 695
   root <- which(is.na(df$parent))
682 696
   # Check if root was found.
683 697
   if(length(root) == 0){
684
-    # Alternatively, root can self reference, eg node = 10, parent = 10
685
-    root <- unlist(apply(df, 1, function(x){ if(x['node'] == x['parent']){ x['node'] } }))
698
+      ## Alternatively, root can self reference, eg node = 10, parent = 10
699
+      root <- df$node[df$parent == df$node]
700
+      ## root <- unlist(apply(df, 1, function(x){ if(x['node'] == x['parent']){ x['node'] } }))
686 701
   }
687 702
   return(root)
688 703
 }
... ...
@@ -4,7 +4,7 @@ ggtree: an R package for visualization and annotation of phylogenetic trees with
4 4
 
5 5
 <img src="https://raw.githubusercontent.com/Bioconductor/BiocStickers/master/ggtree/ggtree.png" height="200" align="right" />
6 6
 
7
-[![releaseVersion](https://img.shields.io/badge/release%20version-1.10.0-green.svg?style=flat)](https://bioconductor.org/packages/ggtree) [![develVersion](https://img.shields.io/badge/devel%20version-1.11.3-green.svg?style=flat)](https://github.com/guangchuangyu/ggtree) [![Bioc](http://www.bioconductor.org/shields/years-in-bioc/ggtree.svg)](https://www.bioconductor.org/packages/devel/bioc/html/ggtree.html#since) [![total](https://img.shields.io/badge/downloads-22621/total-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) [![month](https://img.shields.io/badge/downloads-1218/month-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree)
7
+[![releaseVersion](https://img.shields.io/badge/release%20version-1.10.0-green.svg?style=flat)](https://bioconductor.org/packages/ggtree) [![develVersion](https://img.shields.io/badge/devel%20version-1.11.4-green.svg?style=flat)](https://github.com/guangchuangyu/ggtree) [![Bioc](http://www.bioconductor.org/shields/years-in-bioc/ggtree.svg)](https://www.bioconductor.org/packages/devel/bioc/html/ggtree.html#since) [![total](https://img.shields.io/badge/downloads-22621/total-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) [![month](https://img.shields.io/badge/downloads-1218/month-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree)
8 8
 
9 9
 [![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) [![codecov](https://codecov.io/gh/GuangchuangYu/ggtree/branch/master/graph/badge.svg)](https://codecov.io/gh/GuangchuangYu/ggtree) [![Last-changedate](https://img.shields.io/badge/last%20change-2017--12--21-green.svg)](https://github.com/GuangchuangYu/ggtree/commits/master) [![GitHub forks](https://img.shields.io/github/forks/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/network) [![GitHub stars](https://img.shields.io/github/stars/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/stargazers) [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://awesome-r.com/#awesome-r-graphic-displays)
10 10
 
... ...
@@ -5,7 +5,7 @@ author: "Guangchuang Yu and Tommy Tsan-Yuk Lam\\
5 5
         School of Public Health, The University of Hong Kong"
6 6
 date: "`r Sys.Date()`"
7 7
 bibliography: ggtree.bib
8
-csl: nature.csl
8
+biblio-style: apalike
9 9
 output:
10 10
   prettydoc::html_pretty:
11 11
     toc: true
... ...
@@ -14,7 +14,7 @@ output:
14 14
   pdf_document:
15 15
     toc: true
16 16
 vignette: >
17
-  %\VignetteIndexEntry{00 ggtree introduction}
17
+  %\VignetteIndexEntry{01 ggtree Introduction}
18 18
   %\VignetteEngine{knitr::rmarkdown}
19 19
   %\usepackage[utf8]{inputenc}
20 20
 ---
... ...
@@ -124,14 +124,29 @@ and *daylight* for *unrooted* layout, time-scaled and two dimentional
124 124
 phylogenies. [Tree Visualization](treeVisualization.html) vignette describes
125 125
 these feature in details.
126 126
 
127
-We implement several functions to manipulate a phylogenetic tree.
127
+We implement several functions to manipulate a phylogenetic tree visually,
128
+including viewing selected clade to explore large tree, taxa clustering,
129
+rotating clade or tree, zoom out or collapsing clades *etc.*.
128 130
 
129
-+ taxa can be clustered together using `groupClade` or `groupOTU` functions
130
-+ clades can be collapsed via `collapse` function
131
-+ collapsed clade can be expanded by using `expand` function
132
-+ clade can be re-scale to zoom in or zoom out by `scaleClade` function
133
-+ selected clade can be rotated by 180 degree using `rotate` function
134
-+ position of two selected clades (should share a same parent) can be exchanged by `flip` function
131
+
132
+
133
+```{r treeman, echo=FALSE, out.extra='', message=FALSE}
134
+treeman <- matrix(c(
135
+  "collapse", "collapse a selecting clade",
136
+  "expand", "expand collapsed clade",
137
+  "flip", "exchange position of 2 clades that share a parent node",
138
+  "groupClade", "grouping clades",
139
+  "groupOTU", "grouping OTUs by tracing back to most recent common ancestor",
140
+  "identify", "interactive tree manipulation",
141
+  "rotate", "rotating a selected clade by 180 degree",
142
+  "rotate_tree", "rotating circular layout tree by specific angle",
143
+  "scaleClade", "zoom in or zoom out selecting clade",
144
+  "open_tree", "convert a tree to fan layout by specific open angle"
145
+), ncol=2, byrow=TRUE)
146
+treeman <- as.data.frame(treeman)
147
+colnames(treeman) <- c("Function", "Descriptiotn")
148
+knitr::kable(treeman, caption = "Tree manipulation functions.", booktabs = T)
149
+```
135 150
 
136 151
 
137 152
 Details and examples can be found in [Tree Manipulation](treeManipulation.html) vignette.
... ...
@@ -5,7 +5,7 @@ author: "Guangchuang Yu and Tommy Tsan-Yuk Lam\\
5 5
         School of Public Health, The University of Hong Kong"
6 6
 date: "`r Sys.Date()`"
7 7
 bibliography: ggtree.bib
8
-csl: nature.csl
8
+biblio-style: apalike
9 9
 output:
10 10
   prettydoc::html_pretty:
11 11
     toc: true
... ...
@@ -5,7 +5,7 @@ author: "Guangchuang Yu and Tommy Tsan-Yuk Lam\\
5 5
         School of Public Health, The University of Hong Kong"
6 6
 date: "`r Sys.Date()`"
7 7
 bibliography: ggtree.bib
8
-csl: nature.csl
8
+biblio-style: apalike
9 9
 output:
10 10
   prettydoc::html_pretty:
11 11
     toc: true
... ...
@@ -5,7 +5,7 @@ author: "Guangchuang Yu and Tommy Tsan-Yuk Lam\\
5 5
         School of Public Health, The University of Hong Kong"
6 6
 date: "`r Sys.Date()`"
7 7
 bibliography: ggtree.bib
8
-csl: nature.csl
8
+biblio-style: apalike
9 9
 output:
10 10
   prettydoc::html_pretty:
11 11
     toc: true
... ...
@@ -28,41 +28,62 @@ knitr::opts_chunk$set(tidy = FALSE,
28 28
 ```{r echo=FALSE, results="hide", message=FALSE}
29 29
 library("ape")
30 30
 library("ggplot2")
31
+library("cowplot")
32
+library("treeio")
31 33
 library("ggtree")
34
+
35
+
36
+CRANpkg <- function (pkg) {
37
+    cran <- "https://CRAN.R-project.org/package"
38
+    fmt <- "[%s](%s=%s)"
39
+    sprintf(fmt, pkg, cran, pkg)
40
+}
41
+
42
+Biocpkg <- function (pkg) {
43
+    sprintf("[%s](http://bioconductor.org/packages/%s)", pkg, pkg)
44
+}
32 45
 ```
33 46
 
34 47
 
35
-To view a phylogenetic tree, we first need to parse the tree file into `R`. The `ggtree` package supports many file formats including output files of commonly used software packages in evolutionary biology. For more details, plase refer to the [Tree Data Import](treeImport.html) vignette.
48
+To view a phylogenetic tree, we first need to parse the tree file into *R*. The
49
+`r Biocpkg('ggtree')` package supports many file formats via the `r
50
+Biocpkg('treeio')` package, including output files of commonly used software
51
+packages in evolutionary biology. For more details, plase refer to
52
+the [treeio vignette](https://bioconductor.org/packages/devel/bioc/vignettes/treeio/inst/doc/Importer.html).
36 53
 
37 54
 ```{r}
55
+library("treeio")
38 56
 library("ggtree")
57
+
39 58
 nwk <- system.file("extdata", "sample.nwk", package="treeio")
40 59
 tree <- read.tree(nwk)
41 60
 ```
42 61
 
43
-# Viewing a phylogenetic tree with `ggtree`
62
+# Viewing a phylogenetic tree with *ggtree*
44 63
 
45
-The `ggtree` package extends _`ggplot2`_ package to support viewing phylogenetic tree.
46
-It implements _`geom_tree`_ layer for displaying phylogenetic tree, as shown below:
64
+The `r Biocpkg('ggtree')` package extends `r CRANpkg('ggplot2')` package to support viewing phylogenetic tree.
65
+It implements `geom_tree` layer for displaying phylogenetic tree, as shown below:
47 66
 
48 67
 
49 68
 ```{r fig.width=3, fig.height=3, fig.align="center"}
50 69
 ggplot(tree, aes(x, y)) + geom_tree() + theme_tree()
51 70
 ```
52 71
 
53
-The function, _`ggtree`_, was implemented as a short cut to visualize a tree, and it works exactly the same as shown above.
72
+The function, `ggtree`, was implemented as a short cut to visualize a tree, and it works exactly the same as shown above.
73
+
74
+`r Biocpkg('ggtree')` takes all the advantages of `r CRANpkg('ggplot2')`. For example, we can change the color, size and type of the lines as we do with `r CRANpkg('ggplot2')`.
54 75
 
55
-_`ggtree`_ takes all the advantages of _`ggplot2`_. For example, we can change the color, size and type of the lines as we do with _`ggplot2`_.
56 76
 ```{r fig.width=3, fig.height=3, fig.align="center"}
57 77
 ggtree(tree, color="firebrick", size=1, linetype="dotted")
58 78
 ```
59 79
 
60
-By default, the tree is viewed in ladderize form, user can set the parameter _`ladderize = FALSE`_ to disable it.
80
+By default, the tree is viewed in ladderize form, user can set the parameter *ladderize = FALSE* to disable it.
81
+
61 82
 ```{r fig.width=3, fig.height=3, fig.align="center"}
62 83
 ggtree(tree, ladderize=FALSE)
63 84
 ```
64 85
 
65
-The _`branch.length`_ is used to scale the edge, user can set the parameter _`branch.length = "none"`_ to only view the tree topology (cladogram) or other numerical variable to scale the tree (e.g. _dN/dS_, see also in [Tree Annotation](treeAnnotation.html) vignette).
86
+The *branch.length* is used to scale the edge, user can set the parameter *branch.length = "none"* to only view the tree topology (cladogram) or other numerical variable to scale the tree (*e.g.* _d~N~/d~S~_, see also in [Tree Annotation](treeAnnotation.html) vignette).
66 87
 
67 88
 ```{r fig.width=3, fig.height=3, fig.align="center"}
68 89
 ggtree(tree, branch.length="none")
... ...
@@ -70,79 +91,54 @@ ggtree(tree, branch.length="none")
70 91
 
71 92
 # Layout
72 93
 
73
-Currently, _`ggtree`_ supports several layouts, including:
74
-
75
-+ `rectangular` (by default)
76
-+ `slanted`
77
-+ `circular`
78
-+ `fan`
79
-
80
-for `Phylogram` (by default) and `Cladogram` if user explicitly setting `branch.length='none'`.
81
-`ggtree` also supports `unrooted` layout.
82
-
83
-
84
-## Phylogram
85
-
86
-__`rectangular`__
87
-
88
-```{r fig.height=4, fig.width=4, fig.align="center"}
89
-ggtree(tree) + ggtitle("(Phylogram) rectangular layout")
90
-```
91
-
92
-__`slanted`__
93
-
94
-```{r fig.height=4, fig.width=4, fig.align="center"}
95
-ggtree(tree, layout="slanted") + ggtitle("(Phylogram) slanted layout")
94
+Currently, `r Biocpkg('ggtree')` supports several layouts, including:
95
+
96
++ rectangular (by default)
97
++ slanted
98
++ circular
99
++ fan
100
+
101
+for *phylogram* (by default) and *cladogram* if user explicitly setting
102
+*branch.length='none'*. Unrooted (equal angle and daylight methods), time-scaled
103
+and 2-dimensional layouts are also supported.
104
+
105
+```{r eval=F}
106
+library(ggtree)
107
+set.seed(2017-02-16)
108
+tr <- rtree(50)
109
+ggtree(tr)
110
+ggtree(tr, layout="slanted")
111
+ggtree(tr, layout="circular")
112
+ggtree(tr, layout="fan", open.angle=120)
113
+ggtree(tr, layout="equal_angle")
114
+ggtree(tr, layout="daylight")
115
+ggtree(tr, branch.length='none')
116
+ggtree(tr, branch.length='none', layout='circular')
117
+ggtree(tr, layout="daylight", branch.length = 'none')
118
+```
119
+
120
+```{r echo=F,  fig.width=8, fig.height=8, message=FALSE}
121
+library(ggtree)
122
+set.seed(2017-02-16)
123
+x <- rtree(50)
124
+library(cowplot)
125
+theme_layout <- theme(plot.title = element_text(hjust = 0.5))
126
+plot_grid(
127
+    ggtree(x) + ggtitle("rectangular (phylogram)")+ theme_layout,
128
+    ggtree(x, layout="slanted") + ggtitle("slanted (phylogram)")+theme_layout,
129
+    ggtree(x, layout="circular") + ggtitle("circular (phylogram)")+theme_layout,
130
+    ggtree(x, layout="fan", open.angle=120) + ggtitle("fan (phylogram)")+theme_layout,
131
+    ggtree(x, layout="equal_angle")+ ggtitle("equal angle (unrooted)")+theme_layout,
132
+    ggtree(x, layout="daylight")+ ggtitle("daylight (unrooted)")+theme_layout,
133
+    ggtree(x, branch.length='none')+ ggtitle("rectangular (cladogram)")+theme_layout,
134
+    ggtree(x, branch.length='none', layout='circular')+ ggtitle("circular (cladogram)")+theme_layout,
135
+    ggtree(x, layout="daylight", branch.length = 'none')+ ggtitle("daylight (cladogram)")+theme_layout,
136
+    ncol=3)
96 137
 ```
97 138
 
98
-__`circular`__
99 139
 
100
-```{r fig.height=5, fig.width=5, fig.align="center"}
101
-ggtree(tree, layout="circular") + ggtitle("(Phylogram) circular layout")
102
-```
103
-
104
-__`fan`__
105
-
106
-```{r fig.height=5, fig.width=5, fig.align="center"}
107
-ggtree(tree, layout="fan", open.angle=180) + ggtitle("(Phylogram) fan layout")
108
-```
109 140
 
110 141
 
111
-## Cladogram
112
-
113
-__`rectangular`__
114
-
115
-```{r fig.height=4, fig.width=4, fig.align="center"}
116
-ggtree(tree, branch.length='none') + ggtitle("(Cladogram) rectangular layout")
117
-```
118
-
119
-__`slanted`__
120
-
121
-```{r fig.height=4, fig.width=4, fig.align="center"}
122
-ggtree(tree, layout="slanted", branch.length='none') + ggtitle("(Cladogram) slanted layout")
123
-```
124
-
125
-__`circular`__
126
-
127
-```{r fig.height=5, fig.width=5, fig.align="center"}
128
-ggtree(tree, layout="circular", branch.length="none") + ggtitle("(Cladogram) circular layout")
129
-```
130
-
131
-__`fan`__
132
-
133
-```{r fig.height=5, fig.width=5, fig.align="center"}
134
-ggtree(tree, layout="fan", open.angle=180, branch.length="none") + ggtitle("(Cladogram) circular layout")
135
-```
136
-
137
-
138
-## Unrooted
139
-
140
-Unrooted layout was implemented by the _`equal-angle algorithm`_ that described in _Inferring Phylogenies_[@felsenstein_inferring_2003 pp.578-580].
141
-
142
-```{r fig.height=4, fig.width=4, fig.align="center"}
143
-ggtree(tree, layout="unrooted") + ggtitle("unrooted layout")
144
-```
145
-
146 142
 ## Time-scaled tree
147 143
 
148 144
 A phylogenetic tree can be scaled by time (time-scaled tree) by specifying the parameter, `mrsd` (most recent sampling date).