【问题标题】:How to get event_data for clicked slices in R plotly's sunburst plot如何在 R plotly 的旭日形图中获取单击切片的 event_data
【发布时间】:2020-02-26 04:27:24
【问题描述】:

在 Shiny 应用程序中使用 plotly R 包创建旭日形饼图时,用户可以单击该图以动态放大/缩小。我们希望能够为当前选定/居中的部分下载一些数据。

但是,我们无法从所有可能的 eventdata 选项中找到此信息。有悬停事件,但这还不够,因为用户可以单击一个片段,然后鼠标四处移动以悬停在其他片段上而无需单击它。

放大/缩小没有点击事件。并且没有重新分配事件。我认为必须有一些放大/缩小触发的 js 事件,但这不是用现有的 eventdata 函数捕获的。

更新:js图表似乎有selectedPath属性,但是我不知道如何在Shiny中访问这些数据。

Update2:感谢您解决问题的答案。事实证明,它是 plotly R 包和it has been addd in most recent commit 中缺少的功能。

【问题讨论】:

    标签: shiny r-plotly sunburst-diagram


    【解决方案1】:

    目前plotly_click 仅提供旭日形图的根和叶数据。 但是,一旦单击该图,您就可以将 plotly_hover event_data 传递给 reactiveVal

    由于您没有提供任何示例,请参阅以下内容 - 使用来自 library(shinyjs)onclick() 作为解决方法。

    library(plotly)
    library(shinyjs)
    
    DF <- structure(list(labels = c("total", "A", "C", "B", "F", "E", "F", 
                                    "E", "D", "E", "D", "D", "F", "G", "H", "H", "G", "H", "G", "H", 
                                    "H", "G", "I", "G", "I", "H", "G", "I", "I", "G", "G", "I", "H", 
                                    "H", "I", "I", "I", "H", "I", "G"),
                         values = c(100L, 36L, 29L,
                                    35L, 12L, 14L, 10L, 14L, 8L, 18L, 5L, 10L, 9L, 6L, 5L, 4L, 3L,
                                    7L, 4L, 2L, 6L, 3L, 8L, 3L, 2L, 4L, 4L, 4L, 4L, 4L, 3L, 2L, 5L, 
                                    5L, 2L, 2L, 1L, 1L, 1L, 5L),
                         parents = c(NA, "total", "total", "total", "total - A", "total - C", "total - C", "total - A",
                                     "total - B", "total - B", "total - C", "total - A", "total - B",
                                     "total - A - F", "total - C - E", "total - C - F", "total - A - E",
                                     "total - A - E", "total - B - D", "total - B - D", "total - B - E",
                                     "total - C - D", "total - B - E", "total - A - D", "total - B - D",
                                     "total - B - F", "total - C - F", "total - A - E", "total - C - E",
                                     "total - B - E", "total - B - F", "total - A - D", "total - A - D",
                                     "total - A - F", "total - B - F", "total - C - F", "total - C - D",
                                     "total - C - D", "total - A - F", "total - C - E"),
                         ids = c(
                           "total", "total - A", "total - C", "total - B", "total - A - F", "total - C - E", 
                           "total - C - F", "total - A - E", "total - B - D", "total - B - E", "total - C - D",
                           "total - A - D", "total - B - F", "total - A - F - G", "total - C - E - H",
                           "total - C - F - H", "total - A - E - G", "total - A - E - H", "total - B - D - G",
                           "total - B - D - H", "total - B - E - H", "total - C - D - G", "total - B - E - I",
                           "total - A - D - G", "total - B - D - I", "total - B - F - H", "total - C - F - G",
                           "total - A - E - I", "total - C - E - I", "total - B - E - G", "total - B - F - G",
                           "total - A - D - I", "total - A - D - H", "total - A - F - H", "total - B - F - I",
                           "total - C - F - I", "total - C - D - I", "total - C - D - H", "total - A - F - I",
                           "total - C - E - G"
                         )), row.names = c(NA,-40L), class = "data.frame")
    
    ui <- fluidPage(
      useShinyjs(),
      plotlyOutput("sunburst"),
      htmlOutput("hoverDataOut"),
      htmlOutput("clickDataOut")
    )
    
    server <- function(input, output, session) {
      output$sunburst <- renderPlotly({
        plot_ly(data = DF, source = "sunSource", customdata = ~ids, ids = ~ids, labels= ~labels, parents = ~parents, values= ~values, type='sunburst', branchvalues = 'total')
      })
    
      hoverData <- reactive({
        currentEventData <- unlist(event_data(event = "plotly_hover", source = "sunSource", priority = "event"))
      })
    
      clickData <- reactiveVal()
    
      observe({
        clickData(unlist(event_data(event = "plotly_click", source = "sunSource", priority = "event")))
      })
    
      onclick(id = "sunburst", expr = {clickData(hoverData())})
    
      output$hoverDataOut <- renderText({
        paste("Hover data:", paste(names(hoverData()), unlist(hoverData()), sep = ": ", collapse = " | "))
      })
    
      output$clickDataOut <- renderText({
        paste("Click data:", paste(names(clickData()), unlist(clickData()), sep = ": ", collapse = " | "))
      })
    
    }
    
    shinyApp(ui, server)
    


    我创建了一个 GitHub issue 以获取有关此行为的更多信息。

    您可能还对this post 感兴趣。


    更新: 最新提交后对this的反应plotly_sunburstclick可以使用如下:

    # install latest r-plotly dev version:
    # devtools::install_github("ropensci/plotly")
    
    library(plotly)
    library(shinyjs)
    
    DF <- structure(list(labels = c("total", "A", "C", "B", "F", "E", "F", 
                                    "E", "D", "E", "D", "D", "F", "G", "H", "H", "G", "H", "G", "H", 
                                    "H", "G", "I", "G", "I", "H", "G", "I", "I", "G", "G", "I", "H", 
                                    "H", "I", "I", "I", "H", "I", "G"),
                         values = c(100L, 36L, 29L,
                                    35L, 12L, 14L, 10L, 14L, 8L, 18L, 5L, 10L, 9L, 6L, 5L, 4L, 3L,
                                    7L, 4L, 2L, 6L, 3L, 8L, 3L, 2L, 4L, 4L, 4L, 4L, 4L, 3L, 2L, 5L, 
                                    5L, 2L, 2L, 1L, 1L, 1L, 5L),
                         parents = c(NA, "total", "total", "total", "total - A", "total - C", "total - C", "total - A",
                                     "total - B", "total - B", "total - C", "total - A", "total - B",
                                     "total - A - F", "total - C - E", "total - C - F", "total - A - E",
                                     "total - A - E", "total - B - D", "total - B - D", "total - B - E",
                                     "total - C - D", "total - B - E", "total - A - D", "total - B - D",
                                     "total - B - F", "total - C - F", "total - A - E", "total - C - E",
                                     "total - B - E", "total - B - F", "total - A - D", "total - A - D",
                                     "total - A - F", "total - B - F", "total - C - F", "total - C - D",
                                     "total - C - D", "total - A - F", "total - C - E"),
                         ids = c(
                           "total", "total - A", "total - C", "total - B", "total - A - F", "total - C - E", 
                           "total - C - F", "total - A - E", "total - B - D", "total - B - E", "total - C - D",
                           "total - A - D", "total - B - F", "total - A - F - G", "total - C - E - H",
                           "total - C - F - H", "total - A - E - G", "total - A - E - H", "total - B - D - G",
                           "total - B - D - H", "total - B - E - H", "total - C - D - G", "total - B - E - I",
                           "total - A - D - G", "total - B - D - I", "total - B - F - H", "total - C - F - G",
                           "total - A - E - I", "total - C - E - I", "total - B - E - G", "total - B - F - G",
                           "total - A - D - I", "total - A - D - H", "total - A - F - H", "total - B - F - I",
                           "total - C - F - I", "total - C - D - I", "total - C - D - H", "total - A - F - I",
                           "total - C - E - G"
                         )), row.names = c(NA,-40L), class = "data.frame")
    
    ui <- fluidPage(
      useShinyjs(),
      plotlyOutput("sunburst"),
      htmlOutput("hoverDataOut"),
      htmlOutput("clickDataOut")
    )
    
    server <- function(input, output, session) {
      output$sunburst <- renderPlotly({
        plot_ly(data = DF, source = "sunSource", customdata = ~ids, ids = ~ids, labels= ~labels, parents = ~parents, values= ~values, type='sunburst', branchvalues = 'total')
      })
    
      hoverData <- reactive({
        currentEventData <- unlist(event_data(event = "plotly_hover", source = "sunSource", priority = "event"))
      })
    
      clickData <- reactive({
        currentEventData <- unlist(event_data(event = "plotly_sunburstclick", source = "sunSource", priority = "event"))
      })
    
      output$hoverDataOut <- renderText({
        paste("Hover data:", paste(names(hoverData()), unlist(hoverData()), sep = ": ", collapse = " | "))
      })
    
      output$clickDataOut <- renderText({
        paste("Click data:", paste(names(clickData()), unlist(clickData()), sep = ": ", collapse = " | "))
      })
    
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 这是使用现有信息解决问题的绝佳答案。我认为点击时的悬停信息就足够了,但没有想出这个简单明了的解决方案。我仍然需要检查点击的部分是否是叶子/根的最后一级,因为这会导致缩放变化,但这已经足够了。谢谢!
    • 我无法编辑上面的类型。如果点击的叶子是最后一级,点击它不会缩放图表所以不是我们想要的事件。
    • 顺便说一下,@ismirsehregal,出于我的目的,也许注释掉这一行会更好:observe({ clickData(unlist(event_data(event = "plotly_click"。当点击最后一层叶子时,情节点击事件被触发并被放入 clickData。然而,这种点击不会缩放,也不是我们想要的。注释掉这一点后,点击数据仅在点击非最后一级叶子时更新,因此始终跟踪缩放图表的中心,这正是我们想要的。
    • 好的,我并不完全清楚所需的行为 - 很高兴你找到了方法。
    • 其实为了我们的目的,我们还需要跟踪clickdata的历史。当您单击中心部分时,绘图将缩小,而我们想要的始终是放大/缩小后的中心部分。所以我们需要比较最后一次点击的数据来判断是放大还是缩小。
    猜你喜欢
    • 1970-01-01
    • 2020-07-22
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 2020-11-14
    • 2019-08-11
    • 2012-10-07
    相关资源
    最近更新 更多