Search code examples
ggplot2shinyshinydashboard

Why is fill not working in my ggplot in my shiny app?


I'm trying to replicate the following code into my shiny app:

df1 <- df %>% 
  group_by(xyz, inception_month) %>% 
  summarise(policies = sum(policies))

a <- ggplot(df1, aes(x=as.factor(inception_month), y = policies,  fill = xyz)) +
  geom_bar(position = "fill", stat = "identity") + 
  theme(axis.text.x = element_text(angle = 30, hjust = 1)) +
  xlab("Inception Month") +
  ylab("Policy Count")
print(a)

which gives me the following desired output: enter image description here

However I can't get the fill to display with the following dynamic code:

server <- function(input, output) {

df1 <- reactive({df %>% group_by(input$rating_factor, inception_month) %>% summarise(policies = sum(policies))})

  output$plot <- renderPlot({
    p <- ggplot(data = df1(), aes(x=as.factor(inception_month), y = policies, fill = input$rating_factor)) +
      geom_bar(position = "fill", stat = "identity") +
    theme(axis.text.x = element_text(angle = 30, hjust = 1)) +
      xlab("Inception Month") +
      ylab("Policy Count")

    print(p)
  })
}
shinyApp(ui, server)

df looks like:

df <- data.frame(
  xyz = c("A","A","B","B","B"),
  abc = c("X","X","Y","Y","Y"),
  inception_month = c("Feb 2020", "Nov 2019", "Feb 2020", "Dec 2019", "Feb 2020"),
  policies = c(1, 0, 1, 1, 1))

and the ui is:

library(shiny)
library(shinydashboard)
library(dplyr)
library(ggplot2)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(
    box(plotOutput("plot", height = 250)),

    box(
      title = "Select Rating Factor",
      selectInput("rating_factor", "Rating Factor", c("xyz", "abc"))
  )
  )
))

Solution

  • input$rating_factor creates a character value, which is not what ggplot expects. You need to use !!sym(input$rating_factor) instead.

    I agree with Mason Beau's comment, though. Next time, you should provide a reproducible example. See here or here to know how to make one.

    Edit: As detailed here, you have to use !!sym() in all dplyr functions as well. Here's your corrected example:

    library(shiny)
    library(shinydashboard)
    library(dplyr)
    library(ggplot2)
    
    df <- data.frame(
      xyz = c("A","A","B","B","B"),
      abc = c("X","X","Y","Y","Y"),
      inception_month = c("Feb 2020", "Nov 2019", "Feb 2020", "Dec 2019", "Feb 2020"),
      policies = c(1, 0, 1, 1, 1))
    
    ui <- dashboardPage(
      dashboardHeader(),
      dashboardSidebar(),
      dashboardBody(
        fluidRow(
          box(plotOutput("plot", height = 250)),
    
          box(
            title = "Select Rating Factor",
            selectInput("rating_factor", "Rating Factor", c("xyz", "abc"))
          )
        )
      ))
    
    server <- function(input, output) {
    
      df1 <- reactive({
        df %>% 
          group_by(!!sym(input$rating_factor), inception_month) %>% 
          summarise(policies = sum(policies))
      })
    
      output$plot <- renderPlot({
        p <- ggplot(data = df1(), aes(x=as.factor(inception_month), y = policies, fill = !!sym(input$rating_factor))) +
          geom_bar(position = "fill", stat = "identity") +
          theme(axis.text.x = element_text(angle = 30, hjust = 1)) +
          xlab("Inception Month") +
          ylab("Policy Count")
    
        print(p)
      })
    
    }
    
    shinyApp(ui, server)