【问题标题】:How to use plotly to return the same event_data information for selected points even after modifying the data即使在修改数据后如何使用 plotly 为所选点返回相同的 event_data 信息
【发布时间】:2018-02-28 11:41:07
【问题描述】:

我正在尝试做一些看似简单的事情:当用户单击数据点或使用套索选择选择多个点时,我想用不同的颜色绘制这些点。为此,我查看选择了哪些点,并将col 变量添加到数据框,然后告诉 ggplot 根据该列对点进行着色。

它确实适用于第一个选择。但是,只要已经选择了点,选择下一组点就不起作用。我添加了调试语句以查看从 plotly 返回的数据,并且在初始选择后似乎返回不同的pointNumbercurveNumber。我找不到任何关于这些变量如何工作的文档,而且我不确定如何解决这个问题。

这是GIF showing the issue

这里是重现的代码:

library(plotly)
library(shiny)

ui <- fluidPage(
  plotlyOutput("plot")
)

server <- function(input, output, session) {
  output$plot <- renderPlotly({
    click_data <- event_data("plotly_click", source = "select")
    select_data <- event_data("plotly_selected", source = "select")
    data <- mtcars
    data$col <- "black"
    if (!is.null(select_data)) {
      cat(str(select_data))
      idx <- select_data$pointNumber + 1
      data[idx, "col"] <- "blue"
    }
    if (!is.null(click_data)) {
      cat(str(click_data))
      idx <- click_data$pointNumber + 1
      data[idx, "col"] <- "red"
    }
    p <- ggplot(data, aes(mpg, wt, col = I(col))) + geom_point()
    ggplotly(p, source = "select")
  })
}

shinyApp(ui, server)

我还被告知,也许我需要做的是创建自己的行标识符并将其传递给key 美学。我不确定这意味着什么,我尝试定义key &lt;- row.names(data),然后将key=key 传递给ggplot 的aes(),但这似乎并没有改变任何东西。

【问题讨论】:

    标签: r shiny plotly ggplotly


    【解决方案1】:

    您可以将其映射到您正在绘制的变量:

    library(plotly)
    library(shiny)
    
    ui <- fluidPage(
      plotlyOutput("plot")
    )
    
    server <- function(input, output, session) {
    
      output$plot <- renderPlotly({
        click_data <- event_data("plotly_click", source = "select")
        select_data <- event_data("plotly_selected", source = "select")
    
        data <- mtcars
    
        data$col <- "black"
        if (!is.null(select_data)) {
          idx <- which(data$mpg %in% c(select_data[3]$x) | data$wt %in% c(select_data[4]$y))
          data[idx, "col"] <- "blue"
        }
        if (!is.null(click_data)) {
          idx <- click_data$pointNumber + 1
          data[idx, "col"] <- "red"
        }
        p <- ggplot(data, aes(mpg, wt, col = I(col))) + geom_point()
        ggplotly(p, source = "select")
      })
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 我故意远离那个,因为我担心返回的 x/y 可能并不总是与原始数据中的值完全相同。我试图了解 pointNumber/curveNumber 是如何工作的,这对我来说似乎很奇怪,但显然它背后一定有一些逻辑
    【解决方案2】:

    Carson Sievert 回答了我的问题on a gist

    答案如下:

    我知道这似乎违反直觉,但 pointNumber 不是可靠的行标识符。使用这样的关键变量:

    library(plotly)
    library(shiny)
    
    mtcars$key <- row.names(mtcars)
    mtcars$col <- "black"
    
    ui <- fluidPage(
      plotlyOutput("plot")
    )
    
    server <- function(input, output, session) {
      output$plot <- renderPlotly({
        click_data <- event_data("plotly_click")
        select_data <- event_data("plotly_selected")
        if (!is.null(select_data)) {
          mtcars[mtcars$key %in% select_data$key, "col"] <- "blue"
        }
        if (!is.null(click_data)) {
          mtcars[mtcars$key %in% click_data$key, "col"] <- "red"
        }
        p <- ggplot(mtcars, aes(mpg, wt, col = I(col), key = key)) + 
          geom_point()
        ggplotly(p) %>% layout(dragmode = "lasso")
      })
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 谢谢你 - 知道我们如何在不使用 ggplotly 包装器的情况下将 key 标识符直接传递给 plot_ly 吗?另外,curveNumberpointNumber 是否有任何可能被利用的逻辑?
    • @asifzuba 我添加了一个答案,显示了直接使用plot_ly 的方法。
    【解决方案3】:

    这里是plot_ly的方式,使用customdata属性:

    library(plotly)
    library(shiny)
    
    mtcars$key <- row.names(mtcars)
    mtcars$col <- "black"
    
    ui <- fluidPage(
      plotlyOutput("plot")
    )
    
    server <- function(input, output, session) {
      output$plot <- renderPlotly({
        click_data <- event_data("plotly_click", priority   = "event")
        select_data <- event_data("plotly_selected", priority   = "event")
        if (!is.null(select_data)) {
          mtcars[mtcars$key %in% select_data$customdata, "col"] <- "blue"
        }
        if (!is.null(click_data)) {
          mtcars[mtcars$key %in% click_data$customdata, "col"] <- "red"
        }
        p <- plot_ly(mtcars, x = ~mpg, y=~wt, colors = ~sort(unique(col)), color = ~col, customdata = ~key, type = "scatter", mode = "markers") %>% layout(dragmode = "lasso")
      })
    }
    
    shinyApp(ui, server)
    

    plot_ly 也可以以相同的方式处理 key 参数。但是,customdata 更多的是official way

    key 属性只在 shiny 中支持,但 customdata 是 plotly.js 官方支持,因此也可以用来附加 事件元信息

    可以通过以下方式查看文档:

    library(listviewer)
    schema(jsonedit = interactive())
    

    导航:对象 ► 跟踪 ► 分散 ► 属性 ► 自定义数据

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-29
      • 2021-08-19
      • 2018-07-10
      • 1970-01-01
      • 2016-03-22
      • 2013-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多