brushedPoints includes points not shown in plot?

Just getting started with my first Shiny app, so bear with me... I have a simple Shiny app where I display a ggplot, brush within it, and then show the average value of the brushed points. I use a sliderInput to control the xlim range of the plot.

ggplot displays some blank space on either side of the plot, outside the xlim range. Brushing the plot (I'm using direction=x) allows you to select outside the range of the points that are shown. It appears that when I average my brushedPoints, it averages all the points that are within the brushed range, including points that are not shown in the plot. This could be counterintuitive to my users. Any thoughts on controlling this?

library(shiny)
library(tidyverse)

df <- mtcars

ui <- fluidPage(
  plotOutput('plot',brush=brushOpts(id="plot_brush",direction="x")),
  fluidRow(
    column(6,
           sliderInput("range", label="Range", min = 0, 
                       max = max(df$wt), value = c(0, max(df$wt)))
    ),
    column(6,
           tableOutput("brush_info")
    )  
  )
)

server <- function(input, output) {
  
  output$plot <- renderPlot({
    ggplot(df,aes(x=wt,y=mpg)) +
      geom_point() +
      xlim(input$range)
    
  })
  output$brush_info <- renderTable({
    brushedPoints(df,input$plot_brush) %>% summarize_at(vars(mpg),mean)
  })
}

shinyApp(ui = ui, server = server)

Hi,

Welcome to the RStudio community!

I like to start by saying you created a great reprex! It really helps a lot if the person who posts takes the time to generate one. Great job!

I played around a bit with your code, an indeed it seems that the brush is not respecting the plot limits. Interestingly, brushOpts has an argument Clip which by default is TRUE and thus should prevent the brush from extending into the margins. It does this visually, but not in the values it returns, which is annoying!

I was able to circumvent this by filtering the dataset to the slider values inside the brushedPoints functions like this:

brushedPoints(df %>% filter(between(wt, input$range[1], input$range[2])),
                  input$plot_brush) %>% summarize_at(vars(mpg),mean)

This seems to produce the desired result.
I think we should maybe report this weird behaviour of the brush though, because unless we're both missing something, this will lead to more trouble for others in the future...

Hope this helps,
PJ

Thanks for your solution! I'll wait a little while longer and if there are no other replies I'll post an issue on github and link it back here (and mark your post as the solution).

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.