8

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.

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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)

4 Comments

is there a way to adjust this so that it works for plotly_selected events?
Change to extendShinyjs(text = "shinyjs.resetClick = function() { Shiny.onInputChange('plotly_click-A', 'null'); }") with new version of plotly to make it work, and 'plotly_selected-A' to make it work for selections
So to sum up you should remove .clientValue- from extendShinyjs(text = "shinyjs.resetClick = function() { Shiny.onInputChange('.clientValue-plotly_click-A', 'null'); }")
if you are trying to fix the clicking on the same plotly marker again. Here's the solution. They fixed it on the plotly side.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.