Reputation: 797
This is a follow up to my question here.
I have a plot that is displayed when I start the shiny app, then I want to run some code which "animates" some sampling from the data.
I would like to implement a reset/clear button to reset the plot to it's original state (i.e. as if I had just started the app again). Any ideas?
Working example of my current code:
library(shiny)
library(ggplot2)
invalidateLaterNew <- function (millis, session = getDefaultReactiveDomain(), update = TRUE)
{
if(update){
ctx <- shiny:::.getReactiveEnvironment()$currentContext()
shiny:::timerCallbacks$schedule(millis, function() {
if (!is.null(session) && session$isClosed()) {
return(invisible())
}
ctx$invalidate()
})
invisible()
}
}
unlockBinding("invalidateLater", as.environment("package:shiny"))
assign("invalidateLater", invalidateLaterNew, "package:shiny")
data <- data.frame(ID=1:60,
x=sort(runif(n = 60)),
y=sort(runif(n = 60)+rnorm(60)))
ui <- fluidPage(
sidebarPanel(
sliderInput("n",
"Number of samples:",
min = 10,
max = nrow(data),
value = 20),
sliderInput("surveys",
"Number of surveys:",
min = 1,
max = 10,
value = 5),
actionButton("button", "Go!"),
actionButton("reset", "Reset")
),
# Show the plot
mainPanel(
plotOutput("plot1")
)
)
server <- function(input, output, session) {
plot1 <- NULL
count <- 0
output$plot1 <- renderPlot({
plot1 <<- ggplot(data, aes(x=x, y=y)) + geom_point(colour="red") + theme_bw()
plot1 <<- plot1 + geom_vline(xintercept = mean(data$x), size=1.1, colour="red")
plot1
})
observeEvent(input$button,{
count <<- 0
output$plot1 <- renderPlot({
count <<- count+1
invalidateLater(500, session, count < input$surveys)
data$sampled <- "red"
sample.rows <- sample(data$ID, input$n)
data$sampled[sample.rows] <- "green"
plot1 <<- plot1 + geom_point(x=data$x, y=data$y, colour=data$sampled, size=2)
sample.mean.x <- mean(data$x[sample.rows])
plot1 <<- plot1 + geom_vline(xintercept = sample.mean.x, colour="green")
plot1
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
I have tried wrapping the first renderPlot({...})
call in an observeEvent
call with a reset button input, but no good. I have also tried creating a third renderPlot({...})
call which has an observeEvent
.
I have even tried copying the "original" plot1
to a second variable and recalling that on the reset button, but no luck.
Upvotes: 0
Views: 4427
Reputation: 7704
As per my comment in your previous question I have done the changes by adding plot1<<-NULL
inside the observeEvent
and then again render the original plot.
server <- function(input, output, session) {
plot1 <- NULL
count <- 0
output$plot1 <- renderPlot({
plot1 <<- ggplot(data, aes(x=x, y=y)) + geom_point(colour="red") + theme_bw()
plot1 <<- plot1 + geom_vline(xintercept = mean(data$x), size=1.1, colour="red")
plot1
})
observeEvent(input$button,{
plot1 <<- NULL
output$plot1 <- renderPlot({
plot1 <<- ggplot(data, aes(x=x, y=y)) + geom_point(colour="red") + theme_bw()
plot1 <<- plot1 + geom_vline(xintercept = mean(data$x), size=1.1, colour="red")
plot1
})
count <<- 0
output$plot1 <- renderPlot({
count <<- count+1
invalidateLater(500, session, count < input$surveys)
data$sampled <- "red"
sample.rows <- sample(data$ID, input$n)
data$sampled[sample.rows] <- "green"
plot1 <<- plot1 + geom_point(x=data$x, y=data$y, colour=data$sampled, size=2)
sample.mean.x <- mean(data$x[sample.rows])
plot1 <<- plot1 + geom_vline(xintercept = sample.mean.x, colour="green")
plot1
})
})
}
In the above case you do not need the reset button. In case if you want a reset button you can put the plot<<-NULL
and renderPlot
inside the observeEvent
of the reset button. Something like this:
server <- function(input, output, session) {
plot1 <- NULL
count <- 0
output$plot1 <- renderPlot({
plot1 <<- ggplot(data, aes(x=x, y=y)) + geom_point(colour="red") + theme_bw()
plot1 <<- plot1 + geom_vline(xintercept = mean(data$x), size=1.1, colour="red")
plot1
})
observeEvent(input$button,{
count <<- 0
output$plot1 <- renderPlot({
count <<- count+1
invalidateLater(500, session, count < input$surveys)
data$sampled <- "red"
sample.rows <- sample(data$ID, input$n)
data$sampled[sample.rows] <- "green"
plot1 <<- plot1 + geom_point(x=data$x, y=data$y, colour=data$sampled, size=2)
sample.mean.x <- mean(data$x[sample.rows])
plot1 <<- plot1 + geom_vline(xintercept = sample.mean.x, colour="green")
plot1
})
})
observeEvent(input$reset,{
plot1<<- NULL
output$plot1 <- renderPlot({
plot1 <<- ggplot(data, aes(x=x, y=y)) + geom_point(colour="red") + theme_bw()
plot1 <<- plot1 + geom_vline(xintercept = mean(data$x), size=1.1, colour="red")
plot1
})
})
}
Hope this helps!
Upvotes: 1