1

Using R Shiny and plotly I created a interactive scatter plot.

How can I modify my code to interactively label only the points which were selected by the user?

Example plot

Thank you so much for your help! All the best, Christian

library(plotly)
library(shiny)
library(dplyr)

data <- data.frame(matrix(runif(500,0,1000), ncol = 2, nrow = 100)) %>%
  mutate(ID = row_number())

ui <- fluidPage(
  plotlyOutput("plot"),
  verbatimTextOutput("hover"),
  verbatimTextOutput("click"),
  verbatimTextOutput("brush"),
  verbatimTextOutput("zoom"))

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

  output$plot <- renderPlotly({
    p <- ggplot(data, aes(x = X1, y = X2, key = ID)) +
      geom_point()
    ggplotly(p) %>% layout(dragmode = "select")
  })
}

shinyApp(ui, server)
2
  • I don't understand, your example is not reactive at all and gets never replotted? Anyway, you can update plotly objects without complete redraw using an observer plotlyProxy. Commented Mar 27, 2019 at 13:58
  • Thank you a lot for your comment, AEF! Now I updated my question and added a plot to make it clearer. Commented Mar 27, 2019 at 15:41

1 Answer 1

2

Below is a possible solution. I use a reactive function to "label" selected points. I wasn't sure how exactly you want to display the IDs for selected points. The code adds the ID as text when a point is selected. Also, I add some jitter to move the IDs away from the points.

library(plotly)
library(shiny)
library(dplyr)

data <- data.frame(matrix(runif(500,0,1000), ncol = 2, nrow = 100)) %>%
  mutate(ID = row_number())

ui <- fluidPage(
  plotlyOutput("plot"),
  verbatimTextOutput("hover"),
  verbatimTextOutput("click"),
  verbatimTextOutput("brush"),
  verbatimTextOutput("zoom"))

server <- function(input, output, session) {
  output$plot <- renderPlotly({
    data <- get_data()
    p <- ggplot(data, aes(x = X1, y = X2, key = ID)) +
      geom_point() + geom_text(data=subset(data, show_id),aes(X1,X2,label=ID), position = position_jitter(width = 20,height = 20))
    ggplotly(p, source = "subset") %>% layout(dragmode = "select")
  })

  get_data <- reactive({
    event.data <- event_data("plotly_selected", source = "subset")
    data <- data %>% mutate(show_id = FALSE)
    if (!is.null(event.data)) {
      data$show_id[event.data$pointNumber + 1] <- TRUE
    }
    data
  })
}

shinyApp(ui, server)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, that works! Unfortunately, my real plots contain a few thousands of points, so I was wondering whether it's possible to avoid redrawing the plot and just do an update? Do you know how to do it; e.g. with the help of plotlyProxy()? I wasn't able to find an example of using plotlyProxy() in combination with plotly events.

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.