Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

r

ggplot2

shiny

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)
like image 454
RareAir Avatar asked Jul 10 '16 07:07

RareAir


2 Answers

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.

like image 153
Michal Majka Avatar answered Nov 15 '22 00:11

Michal Majka


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.

like image 45
rosscova Avatar answered Nov 14 '22 22:11

rosscova