rggplot2plotlegendaesthetics

Remove specific items from legend but keep aesthetic the same in ggplot


I would like to remove the no pipe items from the legend in this plot but keep the same plotting aesthetics. I have tried using scale_colour_discrete with breaks, which removed the intended items but it used the default colour palette. I then tried changing the default colour palette but this then changed the appearance of the plot (dashed lines turned grey).

Thanks for your help

enter image description here

set.seed(123)

# Generate the season_df dataframe
season_df <- data.frame(
  t = 1:100,
  Q = c(rnorm(25, mean = 0.5, sd = 0.1), rnorm(25, mean = 0.4, sd = 0.1),
        rnorm(25, mean = 0.3, sd = 0.1), rnorm(25, mean = 0.2, sd = 0.1)),
  MRC = sample(c("Autumn", "Winter", "Spring", "Summer", "Autumn no pipe", "Winter no pipe", "Spring no pipe", "Summer no pipe"), 100, replace = TRUE)
)

# Order levels
season_df$MRC <-
  factor(season_df$MRC,
         levels = c("Autumn", "Autumn no pipe", "Winter", "Winter no pipe", "Spring", "Spring no pipe", "Summer", "Summer no pipe"))

# scale colour manual
cbp2_pipe <- c("#E69F00", "#E69F00",
               "#56B4E9", "#56B4E9",
               "#009E73", "#009E73",
               "#F0E442", "#F0E442",
               "#000000")

scale_colour_discrete <- function(...) {
  scale_colour_manual(..., values = c("#E69F00", "#56B4E9", "#009E73", "#F0E442", "#E69F00", "#56B4E9", "#009E73", "#F0E442"))
}

plot <- season_df %>%
  ggplot(aes(
    x = t,
    y = Q,
    colour = MRC,
    linetype = ifelse(grepl("no pipe", MRC), "soild", "dashed")
  )) +
  geom_line(size = 1) +
  labs(x = "Time (hours)",
       y = "TSA depth (m)") +
  geom_hline(
    yintercept = c(maxTSA_height),
    linetype = 'dashed',
    color = 'black') +
  scale_colour_manual(values = cbp2_pipe) +
  # scale_colour_discrete(breaks = c("Autumn", "Winter", "Spring", "Summer")) +   # Works but dashed lines change to grey 
  scale_linetype(guide = "none") +
  annotate("text", x = 50, y = (maxTSA_height + 0.015), label = "TSA full level", size = 8 / .pt) +
  annotate("text", x = 50, y = (pipe_height_m), label = "Outlet pipe", size = 8 / .pt) +
  theme_classic() +
  theme(
    plot.title = element_blank(),
    axis.text = element_text(size = 8),
    axis.title = element_text(size = 10),
    legend.title = element_blank(),
    legend.text = element_text(size = 8),
    legend.position = "top"
  ) +
  annotate("rect", xmin = -Inf, xmax = Inf, ymin = pipe_base_m, ymax = pipe_top_m, alpha = .1)


plot

Solution

  • Your problem here is that conceptually you have two independent variables - "Season" and "Presence of pipe" that are combined as a single variable in your data. You are tying yourself in knots by trying to plot a single variable as two independent ones, rather than just separating the variable at the start.

    season_df %>%
      mutate(Season = ifelse(grepl("Summer", MRC), "Summer", "Autumn"),
             Season = factor(Season, c("Autumn", "Winter", "Spring", "Summer")),
             Pipe   = ifelse(grepl("pipe", MRC), "No pipe", "Pipe")) %>%
      ggplot(aes(t, Q, colour = Season, linetype = Pipe)) +
      geom_line(size = 1) +
      labs(x = "Time (hours)", y = "TSA depth (m)") +
      geom_hline(yintercept = c(maxTSA_height), linetype = 'dashed', 
                 color = 'black') +
      scale_colour_manual(values = c("#E69F00", "#56B4E9", "#009E73", "#F0E442"),
                          drop = FALSE) +
      annotate("text", x = 50, y = (maxTSA_height + 0.015), 
               label = "TSA full level", size = 8 / .pt) +
      annotate("text", x = 50, y = (pipe_height_m), 
               label = "Outlet pipe", size = 8 / .pt) +
      annotate("rect", xmin = -Inf, xmax = Inf, 
               ymin = pipe_base_m, ymax = pipe_top_m, alpha = .1) +
      guides(colour = guide_legend(order = 1)) +
      theme_classic() +
      theme(
        plot.title = element_blank(),
        axis.text = element_text(size = 8),
        axis.title = element_text(size = 10),
        legend.title = element_blank(),
        legend.text = element_text(size = 8),
        legend.position = "top"
      ) 
    

    enter image description here