1

I used Shiny application to create scatter plots or box plots based on their selection of variables. I got an error with the usage of ggplot2::scale_color_manual() within the renderPlot() function and hence I can't change the colour. I used my own helper function to define the colour first (color_code):

color_code <- function(x) {
  
  if (x %in% c("Semester")) {
    color <- c("#ff0000", "#4472c4")

    } else if (x == "Year") {
    color <- c("Year1" = "#c5e0b4", 
               "Year2" = "#b4c7e7", 
               "Year3" = "#f8cbad", 
               "Final_year" = "#c55a11")
 
    } else {
    # if x != "Semester" or "Year", it can be any colour
    color <- NULL
    
  }
  
  color
  
}

# --------------- app.R ----------------
ui <- fluidPage(
  sidebarPanel(
    selectInput("graphType", "Select Graph Type:", choices = c("scatter", "box")),
    selectInput("x_var", "Select X Variable", choices = names(df)[-1]), 
    selectInput("y_var", "Select Y Variable", choices = names(df)[-1]) 
),
  mainPanel(
    plotOutput("plot1",

...

server <- function(input, output) {
  ranges <- reactiveValues(x = NULL, y = NULL) 
  
  output$plot1 <- renderPlot({
    
    if (input$graphType == "scatter") {
      ggplot(df, aes(x = !!sym(input$x_var), y = !!sym(input$y_var))) +
        geom_point(alpha = 0.5) +
        geom_smooth(method = loess, se = TRUE) +
        ggpubr::stat_cor() +
        theme_bw() + 
        ggplot2::scale_color_manual(values = colour_code(!!sym(input$x_var))) +
        coord_cartesian(xlim = ranges$x, ylim = ranges$y, expand = FALSE)
      
    } else if (input$graphType == "box") {
      ggplot(df, aes(x = !!sym(input$x_var), y = !!sym(input$y_var))) +
        geom_boxplot(color = "black", fill = "white", width = 0.5, size = 1.0, outlier.shape = NA, coef = 1.5) +
        geom_jitter(aes(color = !!sym(input$x_var)), width = 0.1, alpha = 0.5) +
        theme_bw() +
        ggplot2::scale_color_manual(values = colour_code(!!sym(input$x_var))) +
        coord_cartesian(xlim = ranges$x, ylim = ranges$y, expand = FALSE)
    }
  })
...

    }
  })
}

shinyApp(ui, server)

I tried ggplot2::scale_color_manual(values = colour_code(!!sym(input$x_var)))

The error I got is:

Warning: Error in colour_code: unused argument (df) 171: is_missing 170: manual_scale 169: scale_color_manual

If I remove the scale_color_manual() part, the rest of the code works.

How to incorporate my colour_code function into the Shiny app? (not sure if it is relevant , my color_code function is stored in global environment, not in app.R)

1 Answer 1

0

As you did not provide any data to run your code I can only guess what might be the issue. But one evident issue is the use of !!sym(input $x_var) in scale_color_manual which is not necessary. As input$x_var you can pass it directly to your color_code function. Additionally, you use colour_code in your app but according to your code your function is called color_code.

Anyway, here is a working minimal app using mtcars as example data and where I slightly refactored your code, e.g. I moved the plotting code to a separate function to test it outside of your shiny app and hence makes debugging much easier:

colour_code <- function(x) {
  switch(x,
    Semester = c("#ff0000", "#4472c4"),
    Year = c(
      "Year1" = "#c5e0b4",
      "Year2" = "#b4c7e7",
      "Year3" = "#f8cbad",
      "Final_year" = "#c55a11"
    ),
    NULL
  )
}

create_plot <- function(x_var, y_var, type = "scatter") {
  geoms <- if (type == "scatter") {
    list(
      geom_point(aes(color = !!sym(x_var)), alpha = 0.5),
      geom_smooth(method = "loess", formula = y ~ x, se = TRUE),
      ggpubr::stat_cor()
    )
  } else if (type == "box") {
    list(
      geom_boxplot(
        color = "black", fill = "white", width = 0.5,
        size = 1.0, outlier.shape = NA, coef = 1.5
      ),
      geom_jitter(aes(color = !!sym(x_var)), width = 0.1, alpha = 0.5)
    )
  } else {
    return(NULL)
  }
  layers <- list(
    theme_bw(),
    scale_color_manual(values = colour_code(x_var))
    # , coord_cartesian(xlim = ranges$x, ylim = ranges$y, expand = FALSE)
  )

  ggplot(df, aes(x = !!sym(x_var), y = !!sym(y_var))) +
    geoms +
    layers
}

library(ggplot2)
library(dplyr, warn = FALSE)

df <- mtcars |>
  dplyr::select(gear, cyl, am, mpg, hp) |>
  dplyr::mutate(cyl = factor(cyl, labels = paste0("Year", 1:3)), am = factor(am)) |>
  dplyr::rename(Year = cyl, Semester = am)

input <- list(
  graphType = "scatter",
  x_var = "Semester",
  y_var = "hp"
)

create_plot(input$x_var, input$y_var, type = input$graphType)


library(shiny)

ui <- fluidPage(
  sidebarPanel(
    selectInput("graphType", "Select Graph Type:",
      choices = c("scatter", "box"),
      selected = "box"
    ),
    selectInput("x_var", "Select X Variable",
      choices = names(df)[-1],
      selected = "Semester"
    ),
    selectInput("y_var", "Select Y Variable",
      choices = names(df)[-1],
      selected = "mpg"
    )
  ),
  mainPanel(plotOutput("plot1"))
)

server <- function(input, output, session) {
  output$plot1 <- renderPlot({
    create_plot(input$x_var, input$y_var, type = input$graphType)
  })
}

shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:8999

Not the answer you're looking for? Browse other questions tagged or ask your own question.