Reputation: 4643
I have a shiny
app and I want a ggplot
with a brush
at the start, so the user does not need to select certain area of interest every time the app starts. Later of course user can select different area. Here is an example to start with:
library(shiny)
library(ggplot2)
runApp(shinyApp(
ui = fluidPage(plotOutput('plotA', brush = brushOpts(id = 'plotA_brush')),
plotOutput('plotZ')),
server = function(input, output, session) {
pollData <- reactivePoll(60 * 1000, session,
checkFunc = function(){ Sys.time() },
valueFunc = function(){ data.frame(x = 1:100, y = cumsum(rnorm(100)))})
output$plotA <- renderPlot({
dt <- pollData()
ggplot(dt, aes(x, y)) + geom_line()
})
ranges <- reactiveValues(x = NULL, y = NULL)
observe({
brush <- input$plotA_brush
if(!is.null(brush)) {
ranges$x <- c(brush$xmin, brush$xmax)
ranges$y <- c(brush$ymin, brush$ymax)
} else {
ranges$x <- NULL
ranges$y <- NULL
}
})
output$plotZ <- renderPlot({
dt <- pollData()
ggplot(dt, aes(x, y)) + geom_line() + coord_cartesian(xlim = ranges$x, ylim = ranges$y)
})
}
))
Upvotes: 9
Views: 797
Reputation: 7790
Yes, it is possible.
In the code below I've added just a few lines. First, I've added set.seed(42)
so that the graphics are reproducible. Second, there is a dput(brush)
that has been commented out. This was helpful for identifying the initial brush that I wanted to have. Lastly, The in the observe
environment controlling the ranges
I have added a if
else
set to use the default brush
is it is a NULL
value from the input$plotA_brush
object.
library(shiny)
library(ggplot2)
set.seed(42)
runApp(shinyApp(
ui = fluidPage(plotOutput('plotA', brush = brushOpts(id = 'plotA_brush')),
plotOutput('plotZ')),
server = function(input, output, session) {
pollData <- reactivePoll(60 * 1000, session,
checkFunc = function(){ Sys.time() },
valueFunc = function(){ data.frame(x = 1:100, y = cumsum(rnorm(100)))})
output$plotA <- renderPlot({
dt <- pollData()
ggplot(dt, aes(x, y)) + geom_line()
})
ranges <- reactiveValues(x = NULL, y = NULL)
observe({
if (is.null(input$plotA_brush)) {
brush <- structure(list(xmin = 14.313925002001, xmax = 39.942241912585, ymin = 1.1077251080591, ymax = 5.5028180250535, mapping = structure(list( x = "x", y = "y"), .Names = c("x", "y")), domain = structure(list( left = -3.95, right = 104.95, bottom = -4.07771077213569, top = 9.69030145758825), .Names = c("left", "right", "bottom", "top")), range = structure(list(left = 32.3904099935947, right = 674.020527857828, bottom = 368.859578048224, top = 5.47945189149413), .Names = c("left", "right", "bottom", "top")), log = structure(list(x = NULL, y = NULL), .Names = c("x", "y")), direction = "xy", brushId = "plotA_brush", outputId = "plotA"), .Names = c("xmin", "xmax", "ymin", "ymax", "mapping", "domain", "range", "log", "direction", "brushId", "outputId"))
} else {
brush <- input$plotA_brush
}
# dput(brush) # Useful for finding the initial brush
if(!is.null(brush)) {
ranges$x <- c(brush$xmin, brush$xmax)
ranges$y <- c(brush$ymin, brush$ymax)
} else {
ranges$x <- NULL
ranges$y <- NULL
}
})
output$plotZ <- renderPlot({
dt <- pollData()
ggplot(dt, aes(x, y)) + geom_line() + coord_cartesian(xlim = ranges$x, ylim = ranges$y)
})
}
))
The initial starting page looks like this:
Upvotes: 2