Adding manual legend to ggplot2

Hello,

I am trying to figure out how to add a manual legend to a ggplot2 figure. From my reading, you have to add color to aes. However, from all of the examples that I have seen, the color is used for a factor variable. I have a line plot with three continuous variables. I need to add a simple legend for the colors.

ggplot(by_year_percentage, aes(x=arrivaldate)) +
  geom_line(aes(y=deathpercentage), color = "blue", size = 1.5) + 
  geom_line(aes(y=tamponadepercentage), color = "red", size = 1.5) +
  geom_line(aes(y=protaminepercentage), color = "orange", size = 1.5) +
  labs(x="Year", y="(%)")
3 Likes

I think you will get the legend you want if you use gather (or pivot_longer) to bring all the rates into one column and then use group and colour mappings in the aesthetic.

library(tidyr)
df <- gather(by_year_percentage, key = measure, value = Rate, 
c("deathpercentage", "tamponadepercentage", "protaminepercentage"))

ggplot(df, aes(x=arrivaldate, y = Rate, group = measure, colour = measure)) + 
geom_line()

2 Likes

@thisisdaryn 's solution is the tidiest way but if for some reason you need to use separate columns, you can set legends manually this way

library(ggplot2)
colors <- c("Sepal Width" = "blue", "Petal Length" = "red", "Petal Width" = "orange")

ggplot(iris, aes(x = Sepal.Length)) +
    geom_line(aes(y = Sepal.Width, color = "Sepal Width"), size = 1.5) +
    geom_line(aes(y = Petal.Length, color = "Petal Length"), size = 1.5) +
    geom_line(aes(y = Petal.Width, color = "Petal Width"), size = 1.5) +
    labs(x = "Year",
         y = "(%)",
         color = "Legend") +
    scale_color_manual(values = colors)

13 Likes

The previous solution is the best way but if you want to use wide dataframes you can do it with. I would suggest the long format as it makes life a lot easier. You need to map the color to a name in the aes(_) statement and then define the color, fill or shape.

ggplot(by_year_percentage, aes(x=arrivaldate)) +
geom_line(aes(y=deathpercentage, color = "deathpercentage"), size = 1.5) +
geom_line(aes(y=tamponadepercentage, color = "tamponadepercentage"), size = 1.5) +
geom_line(aes(y=protaminepercentage, color = "protaminepercentage"), size = 1.5) +
scale_color_manual(name = "Group",
values = c( "deathpercentage" = "blue", "tamponadepercentage" = "red", "protaminepercentage" = "orange"),
labels = c("deathpercentage", "tamponadepercentage", "protaminepercentage"))

Thank you andresrcs. I do need to keep values in separate columns so your method seemed best. Unfortunately getting stuck on an error message.

colors <- c("Death" = "Blue", "Tamponade" = "Red", "Protamine" = "Orange")

ggplot(by_year_percentage, aes(x=arrivaldate)) +
geom_line(aes(y=deathpercentage), color = "Death", size = 1.5) +
geom_line(aes(y=tamponadepercentage), color = "Red", size = 1.5) +
geom_line(aes(y=protaminepercentage), color = "Orange", size = 1.5) +
labs(x="Year", y="(%)", color = "Legend") +
scale_color_manual(values = colors)

Getting the following error: Error in grDevices::col2rgb(colour, TRUE) : invalid color name 'Death'

Look a little closer to the example, if you want a legend you have to map the columns to the color aesthetic so you have to do it inside aes()

geom_line(aes(y = deathpercentage, color = "Death"), size = 1.5) +

Gah! Thanks!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

I just want to point out that you can keep your underlying data in whatever shape is most convenient and just reshape it temporarily for plotting with ggplot. For example, you can reshape on the fly using the pipe (%>%) operator:

library(tidyverse)

gather(by_year_percentage, key = measure, value = Rate, 
       deathpercentage, tamponadepercentage, protaminepercentage) %>%
  ggplot(aes(x=arrivaldate, y = Rate, group = measure, colour = measure)) + 
    geom_line()

If you're going to be using ggplot regularly, it will work much more effectively if you put your data in "long" format for plotting, regardless of what shape you keep your data in for other purposes.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.