Search code examples
rshinyplotlyr-plotlyggplotly

Retrieve Selected Points from ggplotly in Another Part of Shiny App


Desired Outcome

I would like to be able to click a point in my plotly::ggplotly() graph within my {shiny} app and then display some info about that point in a separate output below.

MRE

In this simple example I can make it display the curveNumber, pointNumber, x, y, but it's not easy to unambiguously retrieve a particular data point from my original data from these values. I've read about using key within the plotly::renderPlotly() call although I'm not sure how I'd access that in a separate part of the app.

library(tidyverse)
library(plotly)
library(shiny)

# UI  ----
ui <- fluidPage(plotlyOutput("plot"),
                verbatimTextOutput("click"))

# server  ----
server <- function(input, output) {
  output$plot <- renderPlotly({
    
    p <- mtcars %>% 
      rownames_to_column("car") %>% 
      ggplot(aes(x = disp, y = mpg, color = factor(cyl),
                 label = car)) +
      geom_point(size = 4, alpha = 0.7)
    
    ggplotly(p) %>% 
      event_register("plotly_click")
  })
  
  output$click <- renderPrint({
    point <- event_data(event = "plotly_click", priority = "event")
    if (is.null(point)) "No Point Selected" else point
  })
}

# app ----
shinyApp(ui = ui, server = server)

enter image description here


Solution

  • Using code from here I figured out how to use key to identify the points and then retrieve that elsewhere from the event_data().

    library(tidyverse)
    library(plotly)
    library(shiny)
    
    d <-  mtcars %>% 
      rownames_to_column("car")
    
    # UI  ----
    ui <- fluidPage(plotlyOutput("plot"),
                    tableOutput("click"))
    
    # server  ----
    server <- function(input, output) {
      output$plot <- renderPlotly({
        
        key <- d$car
        
        p <- d %>% 
          ggplot(aes(x = disp, y = mpg, color = factor(cyl),
                     key = key)) +
          geom_point(size = 4, alpha = 0.7)
        
        ggplotly(p) %>% 
          event_register("plotly_click")
      })
      
      output$click <- renderTable({
        point <- event_data(event = "plotly_click", priority = "event")
        req(point) # to avoid error if no point is clicked
        filter(d, car == point$key) # use the key to find selected point
      })
    }
    
    # app ----
    shinyApp(ui = ui, server = server)
    

    enter image description here