Sam Rogers
Sam Rogers

Reputation: 797

R shiny: reset plot to default state

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

Answers (1)

SBista
SBista

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

Related Questions