ggtree icon indicating copy to clipboard operation
ggtree copied to clipboard

geom_tiplab fails conversion to plotly

Open mmp3 opened this issue 3 years ago • 5 comments

geom_tiplab is causing conversion to plotly via the ggplotly function to fail, and produces a nonsense chart.

Here is a minimal reproducible example from the tree data book, section B.1:

library(MicrobiotaProcess)
library(ggtree)

data(kostic2012crc)
taxa <- phyloseq::tax_table(kostic2012crc)
tree <- as.treedata(taxa)

gp <- ggtree(tree, layout="circular", size=0.2) +
     geom_tiplab(size=1)

gp2  <-  plotly::ggplotly(gp)
htmlwidgets::saveWidget(gp2 ,file="fig.html",selfcontained=TRUE)

which gives Warning message:

Warning messages:
1: In min(z[["x"]]$dimension %()% z$x.range %||% z$x_range) :
  no non-missing arguments to min; returning Inf
2: In max(z[["x"]]$dimension %()% z$x.range %||% z$x_range) :
  no non-missing arguments to max; returning -Inf
3: In min(z[["y"]]$dimension %()% z$y.range %||% z$y_range) :
  no non-missing arguments to min; returning Inf
4: In max(z[["y"]]$dimension %()% z$y.range %||% z$y_range) :
  no non-missing arguments to max; returning -Inf
5: In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
  geom_GeomTextGGtree() has yet to be implemented in plotly.
  If you'd like to see this geom implemented,
  Please open an issue with your example code at
  https://github.com/ropensci/plotly/issues
6: In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
  geom_GeomTextGGtree() has yet to be implemented in plotly.
  If you'd like to see this geom implemented,
  Please open an issue with your example code at
  https://github.com/ropensci/plotly/issues

and the resulting HTML gives a non-interactive, non-sense plot:

image

But if you exclude the geom_tiplab() line, it works. That is, the following works:

library(MicrobiotaProcess)
library(ggtree)

data(kostic2012crc)
taxa <- phyloseq::tax_table(kostic2012crc)
tree <- as.treedata(taxa)

gp <- ggtree(tree, layout="circular", size=0.2) 
gp2  <-  plotly::ggplotly(gp)
htmlwidgets::saveWidget(gp2 ,file="fig.html",selfcontained=TRUE)

Here is some sessionInfo():

> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.1 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8
 [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8
 [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C
[10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] MicrobiotaProcess_1.2.2 ggtree_2.5.2            ggplot2_3.3.3
[4] phyloseq_1.34.0         stringr_1.4.0           data.table_1.14.0


loaded via a namespace (and not attached):
  [1] nlme_3.1-152        matrixStats_0.58.0  progress_1.2.2
  [4] httr_1.4.2          tools_4.0.3         utf8_1.2.1
  [7] R6_2.5.0            vegan_2.5-7         DBI_1.1.1
 [10] lazyeval_0.2.2      BiocGenerics_0.36.1 mgcv_1.8-33
 [13] colorspace_2.0-1    permute_0.9-5       rhdf5filters_1.2.1
 [16] ade4_1.7-16         withr_2.4.2         tidyselect_1.1.1
 [19] gridExtra_2.3       prettyunits_1.1.1   compiler_4.0.3
 [22] Biobase_2.50.0      plotly_4.9.3        sandwich_3.0-0
 [25] labeling_0.4.2      scales_1.1.1        mvtnorm_1.1-1
 [28] digest_0.6.27       XVector_0.30.0      pkgconfig_2.0.3
 [31] htmltools_0.5.0     htmlwidgets_1.5.3   Rmisc_1.5
 [34] rlang_0.4.11        rstudioapi_0.13     farver_2.1.0
 [37] generics_0.1.0      zoo_1.8-8           jsonlite_1.7.2
 [40] crosstalk_1.1.1     gtools_3.8.2        dplyr_1.0.6
 [43] magrittr_2.0.1      modeltools_0.2-23   biomformat_1.18.0
 [46] patchwork_1.1.1     Matrix_1.3-2        Rcpp_1.0.6
 [49] munsell_0.5.0       S4Vectors_0.28.1    Rhdf5lib_1.12.1
 [52] fansi_0.4.2         ape_5.5             lifecycle_1.0.0
 [55] yaml_2.2.1          stringi_1.5.3       multcomp_1.4-17
 [58] ggstar_1.0.2        MASS_7.3-54         zlibbioc_1.36.0
 [61] rhdf5_2.34.0        plyr_1.8.6          grid_4.0.3
 [64] parallel_4.0.3      ggrepel_0.9.1       crayon_1.4.1
 [67] lattice_0.20-41     Biostrings_2.58.0   splines_4.0.3
 [70] multtest_2.46.0     hms_1.0.0           pillar_1.6.0
 [73] igraph_1.2.6        ggsignif_0.6.1      reshape2_1.4.4
 [76] codetools_0.2-18    stats4_4.0.3        glue_1.4.2
 [79] BiocManager_1.30.12 vctrs_0.3.8         treeio_1.15.7
 [82] foreach_1.5.1       gtable_0.3.0        purrr_0.3.4
 [85] tidyr_1.1.3         reshape_0.8.8       assertthat_0.2.1
 [88] coin_1.4-1          libcoin_1.0-8       tidytree_0.3.3
 [91] viridisLite_0.4.0   survival_3.2-7      tibble_3.1.1
 [94] iterators_1.0.13    aplot_0.0.6         rvcheck_0.1.8
 [97] IRanges_2.24.1      cluster_2.1.0       TH.data_1.0-10
[100] ellipsis_0.3.2

mmp3 avatar May 07 '21 17:05 mmp3

Here is an even simpler reproducible example from section A.4.1:

library(ggtree)
## example tree from https://support.bioconductor.org/p/72398/
tree <- read.tree(text= paste("(Organism1.006G249400.1:0.03977,(Organism2.022118m:0.01337,", 
             "(Organism3.J34265.1:0.00284,Organism4.G02633.1:0.00468)0.51:0.0104):0.02469);"))
p <- ggtree(tree) + geom_tiplab()  

p2  <-  plotly::ggplotly(p)
htmlwidgets::saveWidget(p2 ,file="fig.html",selfcontained=T)

which gives message:

Warning message:
In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
  geom_GeomTextGGtree() has yet to be implemented in plotly.
  If you'd like to see this geom implemented,
  Please open an issue with your example code at
  https://github.com/ropensci/plotly/issues

and the tip labels are then excluded from the HTML file.

If we instead try:

p <- ggtree(tree) + geom_text()
p2  <-  plotly::ggplotly(p)

then it says:

Error: geom_text requires the following missing aesthetics: label
Run `rlang::last_error()` to see where the error occurred.

and then rlang::last_error() gives:

> rlang::last_error()
<error/rlang_error>
geom_text requires the following missing aesthetics: label
Backtrace:
 1. plotly::ggplotly(gp)
 2. plotly:::ggplotly.ggplot(gp)
 3. plotly::gg2list(...)
 4. plotly:::ggplotly_build(p)
 5. plotly:::by_layer(function(l, d) l$compute_geom_1(d))
 6. plotly:::f(l = layers[[i]], d = data[[i]])
 7. l$compute_geom_1(d)
 8. ggplot2:::f(..., self = self)
 9. ggplot2:::check_required_aesthetics(...)

and rlang::last_trace() gives:

> rlang::last_trace()
<error/rlang_error>
geom_text requires the following missing aesthetics: label
Backtrace:
    █
 1. ├─plotly::ggplotly(gp)
 2. └─plotly:::ggplotly.ggplot(gp)
 3.   └─plotly::gg2list(...)
 4.     └─plotly:::ggplotly_build(p)
 5.       └─plotly:::by_layer(function(l, d) l$compute_geom_1(d))
 6.         └─plotly:::f(l = layers[[i]], d = data[[i]])
 7.           └─l$compute_geom_1(d)
 8.             └─ggplot2:::f(..., self = self)
 9.               └─ggplot2:::check_required_aesthetics(...)

mmp3 avatar May 07 '21 17:05 mmp3

update. this works and displays correctly on the html:

p <- ggtree(tree) + geom_text(aes(label=label))
p2  <-  plotly::ggplotly(p)

mmp3 avatar May 07 '21 17:05 mmp3

fails with geom_text2 though, based on the example from section 7.1 in the treedata book:

 url <- paste0("https://raw.githubusercontent.com/TreeViz/",
             "metastyle/master/design/viz_targets_exercise/")
x <- read.tree(paste0(url, "tree_boots.nwk"))
info <- read.csv(paste0(url, "tip_data.csv"))

gp  <-  ggtree( x ,
                layout="rectangular",
                branch.length="none",
                size=0.2) +
        geom_text2(aes(label=label ) )
gp2  <-  plotly::ggplotly(gp)
htmlwidgets::saveWidget(gp2 ,file="fig.html",selfcontained=TRUE )

mmp3 avatar May 07 '21 19:05 mmp3

This geom_text2 is the internal geom of ggtree. it is different with geom_text of ggplot2. It seems the plotly links the geom of ggplot2 with geom2trace method. But it doesn't support the extension of ggplot2. To solve the issue, I think you should ask the community of plotly for help.

xiangpin avatar May 27 '21 12:05 xiangpin

Following your last example, you can add tip labels with the following code:

  • Only tip labels: plotly::ggplotly(gp) %>% plotly::add_text(data = gp$data[gp$data$isTip, ], x = ~x, y = ~y, text = ~label, textposition = 'right')

  • All lables: -plotly::ggplotly(gp) %>% plotly::add_text(data = gp$data, x = ~x, y = ~y, text = ~label, textposition = 'right')

JFMSilva avatar Jul 30 '21 23:07 JFMSilva