Search code examples
rggplot2shinyaction-buttonnumeric-input

I cannot introduce new NumericInputs after clicking a "Reset" Button in Shiny


I have written an app in Shiny where you can see a histogram if you click "See the plot".

first image

On the other hand, you have 2 NumericInputs where you can change the min and max values of the x-axis. In fact, if you change those values and click again "See the plot" you will see that the x-axis has changed.

Second image

However, I wanted to have a button to reset the values and recover the original plot. It works.

Third image

The problem is that if you try to change the min and max values to do the process again (after you have clicked the Reset button), you can't. The numbers have been deleted automatically and you are not able to change the values unless you close the app and you open it again.

Maybe the code is too complicated to plot a single histogram, but it is a simple code from the original.

Can anyone help me with this?

Thanks very much.

My code:

library(shiny)
library(ggplot2)

################### DATA ########################
val <- c(2.1490626,3.7928443,2.2035281,1.5927854,3.1399245,2.3967338,3.7915825,4.6691277,3.0727319,2.9230937,2.6239759,3.7664386,4.0160378,1.2500835,4.7648343,0.0000000,5.6740227,2.7510256,3.0709322,2.7998003,4.0809085,2.5178086,5.9713330,2.7779843,3.6724801,4.2648527,3.6841084,2.5597235,3.8477471,2.6587736,2.2742209,4.5862788,6.1989269,4.1167091,3.1769325,4.2404515,5.3627032,4.1576810,4.3387921,1.4024381,0.0000000,4.3999099,3.4381837,4.8269218,2.6308474,5.3481382,4.9549753,4.5389650,1.3002293,2.8648220,2.4015338,2.0962332,2.6774765,3.0581759,2.5786137,5.0539080,3.8545796,4.3429043,4.2233248,2.0434363,4.5980727)
df1 <- data.frame(val)
df1$type <- "Type 1"

val <- c(3.7691229,3.6478055,0.5435826,1.9665861,3.0802654,1.2248374,1.7311236,2.2492826,2.2365337,1.5726119,2.0147144,2.3550348,1.9527204,3.3689502,1.7847986,3.5901329,1.6833872,3.4240479,1.8372175,0.0000000,2.5701453,3.6551315,4.0327091,3.8781182)
df2 <- data.frame(val)
df2$type <- "Type 2"

df3 <- rbind(df1, df2)


################ SHINY APP ########################
ui <- fluidPage(
  
  titlePanel("Histogram"),
  
  sidebarLayout(
    sidebarPanel(
      numericInput("xmin", "Min", value=NULL),
      numericInput("xmax", "Max", value=NULL),
      actionButton("reset", "Reset the x-axis"),
      actionButton("add_plot", "See the plot")
      
    ),
    
    mainPanel(
      plotOutput("plot"),
    )
  )
)

server <- function(session, input, output) {
  
  histogram_function <- reactive({
    
    hist <- ggplot(df3, aes(val, fill=type)) +
      geom_histogram(position = "identity", colour = "grey40", bins = 10) +
      ggtitle("Here must be a title") +
      xlab("Values") +
      ylab("Frequency") +
      facet_grid(type ~ .) + 
      theme(strip.text.x = element_blank(),
            strip.text.y = element_blank())
    
      hist <- hist + coord_cartesian(xlim=c(input$xmin, input$xmax))
      
      
      return(hist)
    
  })
  
  v <- reactiveValues(plot = NULL)
  
  observeEvent(input$add_plot, {
    v$plot <- histogram_function()
  })
  
  observe({
    if(input$reset >0){
      
      updateNumericInput(session, "xmin", "Min", value=NA)
      updateNumericInput(session, "xmax", "Max", value=NA)
      
      v$plot <- histogram_function()
      updateNumericInput(session, "xmin", "Min", value=NULL)
      updateNumericInput(session, "xmax", "Max", value=NULL)
    }
  })
  
  output$plot <- renderPlot({
    if (is.null(v$plot)) return()
    v$plot
  })
  
  
} 

shinyApp(ui = ui, server = server)

Solution

  • I think the following should do the job, all I really added is the plot reset v$plot <- NULL and a dependency with observeEvent

    library(shiny)
    library(ggplot2)
    
    ################### DATA ########################
    val <- c(2.1490626,3.7928443,2.2035281,1.5927854,3.1399245,2.3967338,3.7915825,4.6691277,3.0727319,2.9230937,2.6239759,3.7664386,4.0160378,1.2500835,4.7648343,0.0000000,5.6740227,2.7510256,3.0709322,2.7998003,4.0809085,2.5178086,5.9713330,2.7779843,3.6724801,4.2648527,3.6841084,2.5597235,3.8477471,2.6587736,2.2742209,4.5862788,6.1989269,4.1167091,3.1769325,4.2404515,5.3627032,4.1576810,4.3387921,1.4024381,0.0000000,4.3999099,3.4381837,4.8269218,2.6308474,5.3481382,4.9549753,4.5389650,1.3002293,2.8648220,2.4015338,2.0962332,2.6774765,3.0581759,2.5786137,5.0539080,3.8545796,4.3429043,4.2233248,2.0434363,4.5980727)
    df1 <- data.frame(val)
    df1$type <- "Type 1"
    
    val <- c(3.7691229,3.6478055,0.5435826,1.9665861,3.0802654,1.2248374,1.7311236,2.2492826,2.2365337,1.5726119,2.0147144,2.3550348,1.9527204,3.3689502,1.7847986,3.5901329,1.6833872,3.4240479,1.8372175,0.0000000,2.5701453,3.6551315,4.0327091,3.8781182)
    df2 <- data.frame(val)
    df2$type <- "Type 2"
    
    df3 <- rbind(df1, df2)
    
    
    ################ SHINY APP ########################
    ui <- fluidPage(
        
        titlePanel("Histogram"),
        
        sidebarLayout(
            sidebarPanel(
                numericInput("xmin", "Min", value=NULL),
                numericInput("xmax", "Max", value=NULL),
                actionButton("reset", "Reset the x-axis"),
                actionButton("add_plot", "See the plot")
                
            ),
            
            mainPanel(
                plotOutput("plot"),
            )
        )
    )
    
    server <- function(session, input, output) {
        
        v <- reactiveValues(plot = NULL)
        
        histogram_function <- reactive({
            
            hist <- ggplot(df3, aes(val, fill=type)) +
                geom_histogram(position = "identity", colour = "grey40", bins = 10) +
                ggtitle("Here must be a title") +
                xlab("Values") +
                ylab("Frequency") +
                facet_grid(type ~ .) + 
                theme(strip.text.x = element_blank(),
                      strip.text.y = element_blank())
            
            hist <- hist + coord_cartesian(xlim=c(input$xmin, input$xmax))
            return(hist)
            
        })
        
        observeEvent(input$add_plot, {
            v$plot <- histogram_function()
        })
        
        observeEvent(input$reset,{
            updateNumericInput(session, "xmin", "Min", value=NA)
            updateNumericInput(session, "xmax", "Max", value=NA)
            v$plot <- NULL
        },ignoreNULL = TRUE,ignoreInit = TRUE)
        
        output$plot <- renderPlot({
            if (is.null(v$plot)) {
                return()
            }
            v$plot
        })
        
        
    } 
    
    shinyApp(ui = ui, server = server)
    

    enter image description here