R Shiny, zoomable dendrogram program

血红的双手。 提交于 2021-01-29 06:25:27

问题


I have a massive dendrogram with hundreds of names on it, that I'd like to be make interactive so that users can draw a box and "zoom in" on the names and part of the tree of interest. The original code for creating it is borrowed from here. Pictured here:

I turned it into a shiny app and borrowed some code from here in order to make it zoomable. And it KINDA works. It runs, the two graphs show up, and nothing gives me an error. But it doesn't work as intended. (I'll post code below). What I mean is that if I were to simply render my plot outside of shiny, all the names and everything are included. But when it renders in shiny, I can't draw my box over the names, only the lines of the dendrogram (hope that makes sense), and the "zoomed" graph is turned sideways (something to do with the coord_cartesian? What would I use instead) and looks very weird when it "zooms". Lastly I can't see both graphs at the same time and have to use a scroll bar to get to them, pictured:

Help! Code below (its from an r markdown document if that matters, sorry I couldn't include the actual data, has real names.

Data<-Data%>%select(-`BOARD DATE`)
Data<-t(Data)
Data<-as_tibble(Data)
names(Data) <- Data %>% slice(1) %>% unlist()
Data <- Data %>% slice(-1)

cluster_dtw_h2 <- dtwclust::tsclust(t(Data), 
                                type = "h", 
                                k = 2,  
                                distance = "dtw", 
                                control = hierarchical_control(method = "complete"),
                                preproc = NULL, 
                                args = tsclust_args(dist = list(window.size = 5L)))

hclus <- stats::cutree(cluster_dtw_h2, k = 2) %>% # hclus <- cluster::pam(dist_ts, k = 2)$clustering has a similar result
  as.data.frame(.) %>%
  dplyr::rename(.,cluster_group = .) %>%
  tibble::rownames_to_column("type_col")

hcdata <- ggdendro::dendro_data(cluster_dtw_h2)
names_order <- hcdata$labels$label
hcdata$labels$label <- ""

p1 <- hcdata %>%
ggdendro::ggdendrogram(., rotate=TRUE, leaf_labels=FALSE)


ui <- fluidPage(
fluidRow(

column(width = 12, class = "well",
  h4("Left plot controls right plot"),
  fluidRow(
    column(width = 12,
      plotOutput("plot2", height = 300,
        brush = brushOpts(
          id = "plot2_brush",
          resetOnNew = TRUE
        )
      )
    ),
    column(width = 12,
      plotOutput("plot3", height = 300)
    )
  )
  )

 )
)

server <- function(input, output) {

ranges2 <- reactiveValues(x = NULL, y = NULL)

 output$plot2 <- renderPlot({
  p1
 })

output$plot3 <- renderPlot({
 p1+
  coord_cartesian(xlim = ranges2$x, ylim = ranges2$y, expand = FALSE)
 })

  # When a double-click happens, check if there's a brush on the plot.
  # If so, zoom to the brush bounds; if not, reset the zoom.
  observe({
brush <- input$plot2_brush
if (!is.null(brush)) {
  ranges2$x <- c(brush$xmin, brush$xmax)
  ranges2$y <- c(brush$ymin, brush$ymax)

} else {
  ranges2$x <- NULL
  ranges2$y <- NULL
  }
 })

}


shinyApp(ui=ui, server=server)

回答1:


The tool I'd suggest using is dendextend+ggplot+plotly.

Example:

library(dendextend)
library(ggplot2)
library(plotly)


dend <- USArrests %>%
  dist() %>%
  hclust(method = "ave") %>%
  as.dendrogram()
dend2 <- color_branches(dend, 5)

p <- ggplot(dend2, horiz = T, offset_labels = -3)
ggplotly(p)

The image:

The image after zoom-in:

The one problem here is that the text is clearly not properly aligned (it is for ggplot2 but not in the ggplotly version). This is a bug in plotly that should probably be reported in both dendextend and plotly github repos.



来源:https://stackoverflow.com/questions/63286645/r-shiny-zoomable-dendrogram-program

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!