Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing plotly click event data

Tags:

r

shiny

plotly

I am designing a Shiny app which contains a plotly scatter plot. I would like for the user to be able to click on the graph to record an event using the event_data function, but then be able to clear that event on the click of an actionButton. Some example code can be seen below:

library(shiny)
library(plotly)

ui <- fluidPage(
  actionButton("clearEvent", label = "clear event"),
  verbatimTextOutput("plotVal"),
  plotlyOutput('plot1')
)

server <- function(input, output, session) {
  output$plot1 <- renderPlotly({
    d <- diamonds[sample(nrow(diamonds), 1000), ]
    plot_ly(d, x = ~carat, y = ~price, color = ~carat,
            size = ~carat, text = ~paste("Clarity: ", clarity))
  })

  output$plotVal <- renderPrint({
    e <- event_data("plotly_click")
    if (is.null(e)) {
      NULL
    } else {
      e
    }
  })

  observeEvent(input[["clearEvent"]], {
    e <- NULL
  })
}

shinyApp(ui = ui, server = server)

This doesn't clear the event like I would expect, however. Looking into the code for event_data shows that this is probably because it is stored within the session object itself. Any ideas how I can overwrite it?

The only similar thing I have come across is Clear plotly click event but it's very hacky and doesn't seem to work for me.

like image 895
nathaneastwood Avatar asked Mar 24 '17 09:03

nathaneastwood


2 Answers

In your example, e is just defined in the renderPrint and in the observeEvent and not globally so even if e is changed in the observeEvent, it does not trigger anything in the renderPrint.

You can use reactiveValues for this:

data <- reactiveValues(e=NULL)

  observe({
    data$e <- event_data("plotly_click")
  })

  output$plotVal <- renderPrint({
    e <- data$e
    if (is.null(e)) {
      NULL
    } else {
      e
    }
  })

  observeEvent(input[["clearEvent"]], {
    data$e <- NULL
  })

data$e is changed whenever the user click the plot or the button, and since there is a dependency on data$e in the renderPrint, that gets updated whenever data$e is changed.

like image 103
NicE Avatar answered Oct 19 '22 20:10

NicE


The previous answer partially solves the problem, however, the user cannot click on the same plotly marker again, at least no update is triggered. That problem can be tackled by manually resetting the source of event_data("plotly_click") withshinyjs:

library(shiny)
library(plotly)
library(shinyjs)

ui <- shinyUI(
  fluidPage(
    useShinyjs(),
    # code to reset plotlys event_data("plotly_click", source="A") to NULL -> executed upon action button click
    # note that "A" needs to be replaced with plotly source string if used
    extendShinyjs(text = "shinyjs.resetClick = function() { Shiny.onInputChange('.clientValue-plotly_click-A', 'null'); }"),
    actionButton("reset", "Reset plotly click value"),
    plotlyOutput("plot"),
    verbatimTextOutput("clickevent")
  )
)


server <- shinyServer(function(input, output) {

  output$plot <- renderPlotly({
    plot_ly(mtcars, x=~cyl, y=~mpg)
  })

  output$clickevent <- renderPrint({
    event_data("plotly_click")
  })

  observeEvent(input$reset, {
    js$resetClick()
  })
})

shinyApp(ui, server)
like image 3
shosaco Avatar answered Oct 19 '22 21:10

shosaco