How to change the text and title of legend in ggplot with several variables

Viewed 208

I'm trying to fix my legend text so that the text is representing the appropriate symbols and color. However, I have a lot of variables that I need to include in the legend, and they are all in different columns. Does anyone know a quick way to indicate what the colours and symbol are in the ggplot legend?

Here is some sample code

#sample data
temps = data.frame(Temperature= c(15,25,35), 
                                    Growth.Phase = c("exponential", "stationary", "death"),
                                    Carbohydrates = sample(c(3:10), 9, replace = T),
                                    Lipids = sample(c(10:25), 9, replace = T),
                   Chlorophyll = sample(c(2:15), 9),
                   DNA.RNA = sample(c(3:15), 9),
                   Protein = sample(c(5:20), 9))

temps$Shape = if_else(temps$Growth.Phase == "exponential", 21,
                      if_else(temps$Growth.Phase == "stationary", 22, 23))

#Graph code
ggplot(data = temps, aes(x = Temperature, y = "Proportions", shape = factor(Shape))) +
  geom_point(aes(y = Carbohydrates),colour = "darkred", 
             fill = "darkred", size = 3) +
  geom_line(aes(y = Carbohydrates), size = 1, col = "darkred") +
  geom_point(aes(y = Lipids), colour = "darkblue", 
             fill = "darkblue", size = 3, col ="darkblue") + 
  geom_line(aes(y = Lipids), size = 1) +
  geom_point(aes(y = Protein), colour = "violet", 
             fill = "violet", size = 3) +
  geom_line(aes(y = Protein), size = 1, col ="violet") +
  geom_point(aes(y = DNA.RNA), colour = "darkorange",
             fill = "darkorange", size = 3) +
  geom_line(aes(y = DNA.RNA), size = 1, col = "darkorange") +
  geom_point(aes(y = Chlorophyll), size = 3, colour = "darkgreen",
             fill = "darkgreen") +
  geom_line(aes(y = Chlorophyll), size = 1, col = "darkgreen") +
  labs(x = "Temperature (°C)", y = "Proportion") 

This is the image I am getting

enter image description here

But as you can see it's not giving me the correct text in the legend. I would like the symbols to specify which Growth.Phase they are and the colour to specify what column I have plotted (ie. Carbohydrate, Protein etc....). Does anyone know a quick fix?

When I use my own data this is what the graph looks like, please note the lines are going through the same symbols, and are the same colours

enter image description here

2 Answers

In order to make your code simpler and not have to repeat several times the same line, you can transform your data into a longer format and then use those new variables to attribute color, fill and shape arguments in your aes.

Then, using scale_color_manual or scale_shape_manual, you can set appropriate color and shape.

In order to add lines between appropriate points, I add a "rep" column in order to mimick the rpesence of replicate in your experiments. Otherwise, geom_line can't decide which points are associated together.

library(tidyr)
library(dplyr)
library(ggplot2)

temps %>% mutate(Rep = rep(1:3,each = 3)) %>% 
  pivot_longer(cols = Carbohydrates:Protein, names_to = "Type", values_to = "proportions") %>%
  ggplot(aes(x = Temperature, y = proportions))+
  geom_point(aes(fill = Type, shape = Growth.Phase, color = Type), size = 3)+
  geom_line(aes( color = Type, group =interaction(Rep, Type)))+
  scale_color_manual(values = c("darkred","darkgreen","darkorange","darkblue","violet"))+
  scale_fill_manual(values = c("darkred","darkgreen","darkorange","darkblue","violet"))+
  scale_shape_manual(values = c(23,21,22))+
  labs(x = "Temperature (°C)", y = "Proportion") 

enter image description here

Does it answer your question ?

I'm not sure whether I got the legend right. But the idea is the same as in @dc37's answer. Your plot can be considerably simplified using pivot_longer:

#sample data
temps = data.frame(Temperature= c(15,25,35), 
                   Growth.Phase = c("exponential", "stationary", "death"),
                   Carbohydrates = sample(c(3:10), 9, replace = T),
                   Lipids = sample(c(10:25), 9, replace = T),
                   Chlorophyll = sample(c(2:15), 9),
                   DNA.RNA = sample(c(3:15), 9),
                   Protein = sample(c(5:20), 9))

library(ggplot2)
library(dplyr)
library(tidyr)
library(tibble)

temps_long <- temps %>% 
  pivot_longer(-c(Temperature, Growth.Phase)) %>% 
  mutate(
    shape = case_when(
      Growth.Phase == "exponential" ~ 21,
      Growth.Phase == "stationary" ~ 22,
      TRUE ~ 23
    ),
    color = case_when(
      name == "Carbohydrates" ~ "darkred",
      name == "Lipids" ~ "darkblue",
      name == "Protein" ~ "violet",
      name == "DNA.RNA" ~ "darkorange",
      name == "Chlorophyll" ~ "darkgreen",
      TRUE ~ NA_character_
  ),
  )

# named color vector
colors <- select(temps_long, name, color) %>% 
  distinct() %>% 
  deframe()
# named shape vector
shapes <- select(temps_long, Growth.Phase, shape) %>% 
  distinct() %>% 
  deframe()

ggplot(data = temps_long, aes(x = Temperature, y = value, shape = Growth.Phase, color = name, fill = name, group = Temperature)) +
  geom_point(size = 3) +
  geom_line(size = 1) +
  scale_shape_manual(values = shapes) +
  scale_fill_manual(values = colors) +
  scale_color_manual(values = colors) +
  labs(x = "Temperature (C)", y = "Proportion", color = "XXXX") +
  guides(fill = FALSE, shape = guide_legend(override.aes = list(fill = "black")))

Created on 2020-04-04 by the reprex package (v0.3.0)

Related