Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In plotly, how do I retain the information about both the lasso selection and the clicked point?

I'm using plotly::ggplotly() and I need the user to be able to both select a single point and to select multiple points with brushing. I want both selection options to exist in parallel. The user should be able to click on a point and to lasso select several points, and both of those pieces of information should be recorded.

The problem I'm having is that if I click on a point, then the lasso selection gets reset. But the opposite is not true: if I lasso select and then click on a point, then both are retained.

Here's a GIF of this issue

Here's my code:

library(shiny)
library(plotly)

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

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

  nms <- row.names(mtcars)

  output$plot <- renderPlotly({
    p <- ggplot(mtcars, aes(x = mpg, y = wt, key = nms)) + geom_point()
    ggplotly(p) %>% layout(dragmode = "lasso")
  })

  output$click <- renderPrint({
    d <- event_data("plotly_click")
    if (!is.null(d)) d
  })

  output$brush <- renderPrint({
    d <- event_data("plotly_selected")
    if (!is.null(d)) d
  })

}

shinyApp(ui, server)

To reproduce:

  • Click a single point
  • Do a lasso selection
  • Both are currently visible
  • Click a different point
  • Now the lasso selection information is gone
  • Do a lasso selection again, both are visible again
like image 270
DeanAttali Avatar asked Nov 08 '22 16:11

DeanAttali


1 Answers

If you pass the event_data to an object outside the renderPrint() function this should work. You can also keep previous lasso/click results if you remove the optional lines highlighted below:

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

server <- function(input, output, session) {
    frame1 <- data.frame()
    frame2 <- data.frame()
    nms <- row.names(mtcars)

    output$plot <- renderPlotly({
        p <- ggplot(mtcars, aes(x = mpg, y = wt, key = nms)) + geom_point()
        ggplotly(p) %>% layout(dragmode = "lasso")
    })

    output$click <- renderPrint({
        d <- event_data("plotly_click")
        if (!is.null(d)) {
            frame1 <<- frame1[is.null(frame1$pointNumber), ] # Optional line to remove the previous selections
            frame1 <<- rbind(frame1, d) 
        }
            frame1
        })

    output$brush <- renderPrint({
        d <- event_data("plotly_selected")
        if (!is.null(d)) {
            frame2 <<- frame2[is.null(frame2$pointNumber), ] # Optional line to remove the previous selections 
            frame2 <<- rbind(frame2, d)
        }
            frame2

    })

}

shinyApp(ui, server)
like image 144
KGee Avatar answered Nov 15 '22 05:11

KGee