0

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)
emr2
  • 1,436
  • 7
  • 23

1 Answers1

1

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

Pork Chop
  • 28,528
  • 5
  • 63
  • 77
  • Thanks very much! Could you explain me why do you use ignoreNULL = TRUE and ignoreInit = TRUE? I have never used them and I don't know what they do. – emr2 Apr 27 '21 at 18:59
  • So those are fo initiation, first time you load it wont trigger by defailt, hence the ` ignoreInit = TRUE`, then if it is every a `NULL` it wont trigger also hence the `ignoreNULL = TRUE` – Pork Chop Apr 27 '21 at 19:05