@@ -179,7 +179,13 @@ AlignPhylo <- ggproto("AlignPhylo", Align,
179
179
# ' @inheritParams fortify_data_frame.dendrogram
180
180
# ' @param tree_type A single string, one of
181
181
# ' `r oxford_or(c("phylogram", "cladogram"))`, indicating the type of tree.
182
+ # ' - `phylogram`: Represents a phylogenetic tree where branch lengths indicate
183
+ # ' evolutionary distance or time.
184
+ # ' - `cladogram`: Represents a tree where branch lengths are not used, or the
185
+ # ' branches do not reflect evolutionary time.
186
+ # '
182
187
# ' Usually, you don't need to modify this.
188
+ # '
183
189
# ' @param tip_pos The x-coordinates of the tip. Must be the same length
184
190
# ' of the number of tips in `tree`.
185
191
# ' @return A `data frame` with the node coordinates:
@@ -212,8 +218,8 @@ fortify_data_frame.phylo <- function(data, ..., type = "rectangle",
212
218
))
213
219
}
214
220
}
215
- if (is.null( edge_lengths ) || identical(tree_type , " cladogram" )) {
216
- edge_lengths <- seq_len(nrow( edge ))
221
+ if (identical(tree_type , " cladogram" )) {
222
+ edge_lengths <- NULL
217
223
}
218
224
parent <- edge [, 1L , drop = TRUE ]
219
225
child <- edge [, 2L , drop = TRUE ]
@@ -228,18 +234,22 @@ fortify_data_frame.phylo <- function(data, ..., type = "rectangle",
228
234
)
229
235
}
230
236
i <- 0L # tip index
231
- phylo_data <- function (index , timing , from_root = TRUE ) {
237
+ phylo_data <- function (index , level , timing ) {
232
238
if (any(select <- parent == index )) {
233
- y <- timing
239
+ # recursively for each child
240
+ data <- list (index = child [select ])
241
+ # if we have edge length, timing should be available
242
+ if (! is.null(edge_lengths )) {
243
+ data <- c(data , list (timing = timing + edge_lengths [select ]))
244
+ }
234
245
data <- list_transpose(.mapply(
235
- function (index , timing ) {
236
- phylo_data(index , timing , from_root = FALSE )
246
+ function (index , timing = NULL ) {
247
+ phylo_data(index , level = level + 1L , timing = timing )
237
248
},
238
- list (
239
- index = child [select ],
240
- timing = timing + edge_lengths [select ]
241
- ), NULL
249
+ data , NULL
242
250
))
251
+
252
+ # integrate the data for each child
243
253
node <- vec_rbind(!!! .subset2(data , " node" ))
244
254
edge <- vec_rbind(!!! .subset2(data , " edge" ))
245
255
@@ -266,6 +276,13 @@ fortify_data_frame.phylo <- function(data, ..., type = "rectangle",
266
276
x <- sum(range(direct_leaves_x )) / 2L
267
277
}
268
278
279
+ # y coordinate for current node
280
+ if (is.null(edge_lengths ) && is.null(timing )) {
281
+ y <- min(direct_leaves_y ) * level / (level + 1L )
282
+ } else {
283
+ y <- timing
284
+ }
285
+
269
286
# there is no node data for the root
270
287
node <- vec_rbind(data_frame0(
271
288
.index = index ,
@@ -309,7 +326,11 @@ fortify_data_frame.phylo <- function(data, ..., type = "rectangle",
309
326
} else if (any(select <- child == index )) { # for the tip
310
327
i <<- i + 1L
311
328
x <- tip_pos [i ]
312
- y <- edge_lengths [select ] + timing
329
+ if (is.null(edge_lengths )) {
330
+ y <- 1L
331
+ } else {
332
+ y <- edge_lengths [select ] + timing
333
+ }
313
334
list (
314
335
node = data_frame0(
315
336
.index = index ,
@@ -327,6 +348,6 @@ fortify_data_frame.phylo <- function(data, ..., type = "rectangle",
327
348
}
328
349
329
350
# from ape::is.rooted, this should be the most ancester
330
- ans <- phylo_data(N + 1L , 0L )
351
+ ans <- phylo_data(N + 1L , 0L , timing = 0 )
331
352
ggalign_attr_set(.subset2(ans , " node" ), list (edge = .subset2(ans , " edge" )))
332
353
}
0 commit comments