LePhasme
LePhasme

Reputation: 3

Adding legend for geom_line to ggplot

I'm generating a chart line graph with ggplot, the main purpose of the graph it to display some sample values over time for some points(the number of points can vary, there is one line for each point). There is also a line I added to show if the values exceed a predefined limit. I get a legend on the right that map each point, but I didn't manage to add a legend for the limit. Here is the code that generate the graph :

library(ggplot2)
df2 <- subset(dataset, ResultNumericValue < 1000000)
names(df2)[4] <- "PointName"
df2[[1]] <- as.POSIXct(df2[[1]], tz="GMT", format="%Y-%m-%dT%H:%M")
ggplot(df2, aes(x=SampleDate, y=ResultNumericValue)) +
  geom_line(aes(color=PointName)) +
  geom_point(aes(color=PointName))+
  geom_line(aes(y = UpperLimit, color=UpperLimit), color="red", size=1) +
  labs(x = "Sample Date", y = "Sample Value", color="Points") +
  theme(panel.grid.major = element_line(color = "darkgrey", size = 0.5, linetype = 3),
  panel.background = element_rect(fill = "white", colour = "grey50"))

The looks like this :

                SampleDate           ResultNumericValue  UpperLimit    point name
1 2020-03-03T16:00:00.0000000                  4         13            1
2 2020-03-05T16:00:00.0000000                  1         13            1
3 2020-03-23T07:30:48.2870000                  2         13            1
4 2020-03-24T00:07:43.6030000                  1         13            CW1
5 2020-03-24T06:56:41.1170000                  2         13            CW1

And this is what the graph look like : graph

I just would like to add something to explain that the red horizontal line is the upper limit. I tried to use the scale_discrete_manual but it changes the sites legend. What should I do ?

Upvotes: 0

Views: 1783

Answers (2)

Allan Cameron
Allan Cameron

Reputation: 173803

A simple way to deal with this is to use a geom_hline for the upper limit. If you map its linetype to the string 'Upper Limit' it will have its own separate entry in the legend.

ggplot(df2, aes(SampleDate, ResultNumericValue, color = PointName)) +
  geom_line() +
  geom_point() +
  geom_hline(aes(yintercept = 13, linetype = 'Upper Limit'), color = "red", 
             size = 1) +
  labs(x = "Sample Date", y = "Sample Value", 
       color = "Points", linetype = NULL) +
  theme(panel.grid.major = element_line(color = "darkgrey", 
                                        size = 0.5, linetype = 3),
        panel.background = element_rect(fill = "white", colour = "grey50"))

enter image description here

Upvotes: 1

stefan
stefan

Reputation: 124148

The issue is that you passed the color as an argument. If you want to have your line displayed in the legend you have to map on the color aes. To this end map a constant value e.g. "UpperLimit" on the color aes and set your desired colors via scale_color_manual. Additionally I used the override.aes argument of guide_legend to remove the points from the legend keys for the upper limit line:

library(ggplot2)
df2 <- subset(dataset, ResultNumericValue < 1000000)
names(df2)[4] <- "PointName"
df2[[1]] <- as.POSIXct(df2[[1]], tz = "GMT", format = "%Y-%m-%dT%H:%M")
ggplot(df2, aes(x = SampleDate, y = ResultNumericValue)) +
  geom_line(aes(color = PointName)) +
  geom_point(aes(color = PointName)) +
  geom_line(aes(y = UpperLimit, color = "UpperLimit"), size = 1) +
  labs(x = "Sample Date", y = "Sample Value", color = "Points") +
  theme(
    panel.grid.major = element_line(color = "darkgrey", size = 0.5, linetype = 3),
    panel.background = element_rect(fill = "white", colour = "grey50")
  ) +
  scale_color_manual(values = c("1" = "blue", CW1 = "green", UpperLimit = "red")) +
  guides(color = guide_legend(override.aes = list(shape = c(16, 16, NA))))

DATA

dataset <- structure(list(
  SampleDate = c(
    "2020-03-03T16:00:00.0000000",
    "2020-03-05T16:00:00.0000000", "2020-03-23T07:30:48.2870000",
    "2020-03-24T00:07:43.6030000", "2020-03-24T06:56:41.1170000"
  ),
  ResultNumericValue = c(4L, 1L, 2L, 1L, 2L), UpperLimit = c(
    13L,
    13L, 13L, 13L, 13L
  ), point.name = c(
    "1", "1", "1", "CW1",
    "CW1"
  )
), class = "data.frame", row.names = c(
  "1", "2", "3",
  "4", "5"
))

Upvotes: 1

Related Questions