Plots in shiny support click and brush handlers. Is it possible to "clear"/"remove"/"delete" the brushed rectangle without having the user click elsewhere on the plot? For example, if I wanted to just store the brushed coordinates once the brush is finished and then clear the plot, this is the code I would use but I don't know how to do the clearing bit.
library(ggplot2)
library(shiny)
runApp(shinyApp(
ui = fluidPage(
plotOutput("plot",
brush = brushOpts("plotBrush", delay = 5000)),
actionButton("clear", "Clear")
),
server = function(input, output, session) {
values <- reactiveValues(brush = NULL)
output$plot <- renderPlot({
ggplot(cars, aes(speed, dist)) + geom_point()
})
brush <- reactive({
input$plotBrush
})
observeEvent(input$clear, {
cat(str(brush()))
# clear the brushed area
})
}
))
As of Shiny version 0.14, it is possible to use the session
object to reset a plot's brush.
Below is a simple Shiny app demoing the use of session$resetBrush(<BRUSH_ID>)
to clear away a brushed region. The app allows one to highlight a region of points or remove the brushed region while keeping the points highlighted or remove the brushed region and reset the color of the points.
See about halfway down at https://shiny.rstudio.com/reference/shiny/latest/session.html for the official documentation.
library(shiny)
library(ggplot2)
shinyApp(
ui = fluidPage(
plotOutput(
outputId = "plot",
brush = brushOpts(
id = "plotBrush",
delay = 5000
)
),
actionButton("clearBrush", "Clear brush"),
actionButton("resetPlot", "Reset plot")
),
server = function(input, output, session) {
output$plot <- renderPlot({
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_point(
data = brushedPoints(mtcars, brush),
color = "#79D8CB",
size = 2
)
})
brush <- NULL
makeReactiveBinding("brush")
observeEvent(input$plotBrush, {
brush <<- input$plotBrush
})
observeEvent(input$clearBrush, {
session$resetBrush("plotBrush")
})
observeEvent(input$resetPlot, {
session$resetBrush("plotBrush")
brush <<- NULL
})
}
)
I find myself in a similar situation where I have multiple brushes and need a button to "clear the world". I haven't found an official way to remove the brush div with R code, but it turns out there is this awesome package called shinyjs ;)
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("clear", "Clear brush"),
fluidRow(
column(
width = 6,
plotOutput("p1", brush = brushOpts("b1"))
),
column(
width = 6,
plotOutput("p2", brush = brushOpts("b2"))
)
),
fluidRow(
column(
width = 6,
verbatimTextOutput("brush1")
),
column(
width = 6,
verbatimTextOutput("brush2")
)
)
)
server <- function(input, output) {
values <- reactiveValues(
brush1 = NULL,
brush2 = NULL
)
# update reactive values when input values change
observe({
values$brush1 <- input$b1
values$brush2 <- input$b2
})
# display brush details
output$brush1 <- renderPrint({
values$brush1
})
output$brush2 <- renderPrint({
values$brush2
})
# clear brush values and remove the div from the page
observeEvent(input$clear, {
values$brush1 <- NULL
values$brush2 <- NULL
runjs("document.getElementById('p1_brush').remove()")
runjs("document.getElementById('p2_brush').remove()")
})
output$p1 <- renderPlot({
input$clear
m <- brushedPoints(mtcars, values$brush1, allRows = TRUE)
qplot(data = m, wt, mpg, colour = selected_) +
theme(legend.position = "none")
})
output$p2 <- renderPlot({
input$clear
m <- brushedPoints(mtcars, values$brush2, allRows = TRUE)
qplot(data = m, wt, mpg, colour = selected_) +
theme(legend.position = "none")
})
}
shinyApp(ui, server)
IMO, shiny should really provide something like:
clearBrush <- function(id) {
shinyjs::runjs(sprintf("document.getElementById('%s_brush').remove()", id))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With