How do I create a reactive plot using ggplot in Shiny application

10,319

Solution 1

The ui works fine, however; the server function generates an empty plot.

This is most likely due to the fact that the function subset returns an empty dataset. In order to debug the code, first, I would print out in the console this part:

C2 <- reactive(subset(CONQDF,input$Demog %in% levels(input$Demog)[1] & CONQDF$VW_Model == input$Car))

I believe that this part is wrong because input$Demog is just a character string and not a factor. That's why levels(input$Demog) = NULL and input$Demog %in% levels(input$Demog) = FALSE. Hence, as a result, you get an empty dataset.

To check this:

output$P1 <- renderPlot({
    print(C2()) # print it out to the console.
    ggplot(C2(),aes_string(x="CompMake", y=input$Metric))+ geom_bar(stat = "identity")
})

If this is the case, you only need to re-think subsetting part.

Solution 2

It looks like your C2 function can't see CONQDF (hence the blank plot). You can add () after CONQDF in your C2 call to run that read.csv every time, but you're probably better off moving the read.csv outside your server function altogether.

So move this line

CONQDF <- read.csv("C:/Users/Reginald/Desktop/CONQ_VW/CONQUEST2.csv")

to the top of your script, just below library(dplyr). This will make shiny read that file when the page first loads, instead of every time the input is updated, and will also place the resulting dataframe into the global environment, which will mean your C2 <- call will be able to see it.

I can't easily reproduce your app, so I can't test my answer. Please let me know whether or not it helps.

Share:
10,319
RareAir
Author by

RareAir

Updated on June 09, 2022

Comments

  • RareAir
    RareAir almost 2 years

    I have spent several hours trying to figure out how to generate a bar plot using ggplot2 for a shiny app I want to create. The ui works fine, however; the server function generates an empty plot.

    The issue is with renderPlot function. I believe I must not be passing the reactive values properly to the aes_string arguments in ggplot. C2 is a filtered dataset. The goal is to build a simple app in which the user selects a two variables, a dataset is filtered based upon those variables. The subsetted dataset is passed to ggplot data argument.

           library(shiny)
    library(dplyr)
    
    
    ui <- fluidPage(
      sidebarLayout(
        sidebarPanel(
          selectInput(inputId = "Demog",label = "Factor:",choices = c("HH Income" = "Income",
                                                                      "Age Group" = "Age",
                                                                      "US Region" = "Region") , selected = "Age"),
          selectInput(inputId = "Car",label = "VW Model:",choices = c("BEETLE" = "BEETLE",
                                                                      "CC" = "CC",
                                                                      "EOS" = "EOS",
                                                                      "GOLF" = "GOLF",
                                                                      "GTI" ="GOLF SPORTSWAGEN GTI",
                                                                      "JETTA" = "JETTA",
                                                                      "PASSAT" = "PASSAT",
                                                                      "TIGUAN" = "TIGUAN",
                                                                      "TOUAREG" = "TOUAREG") , selected = "BEETLE"),
          radioButtons(inputId = "Metric",label ="Measurement Type",choices = 
                         c("Conquest Volume Index" = "TotCmpConqVol_IDX","C/D Ratio" = "TotCmpCDRatio_IDX"), selected = "TotCmpConqVol_IDX" )                
    
        )
      ),
      mainPanel(
        tags$h1("The Bar Charts"),
        tags$h2("The metrics"),
    
    
        plotOutput("P1")
    
      )
    
    )
    server <- function(input, output){
      library(ggplot2)
      CONQDF <- read.csv("C:/Users/Reginald/Desktop/CONQ_VW/CONQUEST2.csv")
    
      C2 <- reactive(subset(CONQDF,input$Demog %in% levels(input$Demog)[1] & CONQDF$VW_Model == input$Car))
    
      output$P1 <- renderPlot({
        ggplot(C2(),aes_string(x="CompMake", y=input$Metric))+ geom_bar(stat = "identity")
                              })
    }
    
    
    
    
    
    
    shinyApp(ui,server)
    
  • Michal Majka
    Michal Majka almost 8 years
    To make debuging easier you can also define an observer in which you'll print out inputs and/or results of the manipulation of inputs. For instance: observe({ print(levels(input$Demog)) })
  • RareAir
    RareAir almost 8 years
    Thank you rosscova. I am sort of new to real programming so it never occurred to me that this could be a scoping issue ( I have just started reading about this). It did not work when I moved the code just below library(dplyr) but your logic makes sense and I will leave it there. I will use an example dataset as suggested by you and @Mikael. If I can not resolve in the next couple of hours I will repost with example dataset.
  • RareAir
    RareAir almost 8 years
    Thank you. I am learning a lot from these answers. I will attempt the debug suggestion you gave above. I appreciate it and I will let you know if that helps me get to the right solution.
  • rosscova
    rosscova almost 8 years
    No worries, let us know how you go.
  • RareAir
    RareAir almost 8 years
    I did. What's next? All the advice I received helped some what. Do I need to do something else on the site? Let me know. thanks
  • rosscova
    rosscova almost 8 years
    It's a good idea to mark the answer that helped you as accepted, that way others will find the most useful answer more easily when they're searching. If you resolved the issue yourself, you can also post your own answer, and accept that. Either way, try to provide a resolution; your post may be useful for others having the same issue. That's what SO is all about :)