Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2: how to differentiate click from brush?

Tags:

r

ggplot2

shiny

I want to have a plot in my shiny app that the user can click on or choose certain regions, so I'm using the click and brush arguments of plotOutput. My problem is that when a brush is initiated, the click handler is also called. I want to know when a click is made, and I want to know when a brush is made, but if a click is part of a brush then I want to ignore it.

Example: in the following app, if you just brush (click somewhere and drag the mouse), you get a "click" message as well as a "brush" message. I want to only get the "brush" message in that case.

library(shiny)
library(ggplot2)
runApp(shinyApp(
  ui = fluidPage(
    plotOutput("plot", click = "click", brush = "brush")
  ),
  server = function(input, output, session) {
    output$plot <- renderPlot({
      ggplot(mtcars, aes(wt, mpg)) + geom_point()
    })
    observeEvent(input$click, {
      cat("clicked\n")
    })
    observeEvent(input$brush, {
      cat("brushed\n")
    })
  }
))
like image 645
DeanAttali Avatar asked May 29 '15 11:05

DeanAttali


1 Answers

I know it's just a workaround, but my only solution for this was to undo the action of the last click when the brush is activated; I needed this for a plot where the user could add points by clicking. Using the brushing will first create the point and remove it after releasing the click button. Just a drawback: sometimes you click and do a micro-brush without noticing, in this case it won't create the point obviously. My app:

library(shiny); library(dplyr); library(ggplot2)

ui <- fluidPage(
     fluidRow(

          h1("add by clicking anywhere on the plot"),
          plotOutput("mainplot",
                     click="mainplot_click",
          brush=brushOpts(id="mainplot_brush"))
     ),
     fluidRow(
          actionButton("add", "add"),
          actionButton("reset", "reset")
     )
)

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

     vals = reactiveValues(
          keeprows = rep(TRUE, nrow(mtcars)),
          mydata = mtcars
     )

     observeEvent(input$mainplot_click, handlerExpr = {
          my.x = input$mainplot_click$x
          my.y = input$mainplot_click$y
          vals$mydata <- vals$mydata %>% bind_rows(data.frame("wt"=my.x, "mpg"=my.y))
     })

     output$mainplot = renderPlot({
          temp = vals$mydata
          ggplot() +geom_point(data=temp, col="black", fill="white", size=3) + aes(x=wt, y=mpg)
     })

     observeEvent(input$mainplot_brush, handlerExpr = {
           vals$mydata <- vals$mydata %>% head(-1)
     })

     observeEvent(input$reset, handlerExpr = {
          vals$mydata <- mtcars
          vals$keeprows <- rep(TRUE, nrow(mtcars))
     })
     session$onSessionEnded(stopApp)
}

shinyApp(ui, server)
like image 107
agenis Avatar answered Oct 14 '22 23:10

agenis