2

I have this plot with dodge bars for 2 series: 2019-2018 and lines for 3 different series: 2015-2017 with enrollment by week for each year. When working the legend, I need to displays keys only for 2018-2019 ( bars) and 2017 (black line). For the other series I will work with annotate text which works fine. So, my issue is to add only one line to the legend when I have at least 2 geom_line objects( one for 2017 and a second one for 2015-2016), or 3 objects geom_line, one for each year form 2015-2017. One of two things happens: either the legend for 2019 doesn't show up or in my second version of code, the line is inside the keys for bars in legend. See below my code:

# This is my simulated data - plot looks horrible but with real data looks way better -please do not judge
data <- data.frame(week=rep(1:52,5),
                   year=rep(2015:2019, each=52),
                   freq=sample(100,260, TRUE))
data$year <- as.character(data$year)
data$freq[data$year=="2019"] <- sample(30,52, TRUE)
data$freq[data$year=="2018"] <- sample(30,52, TRUE)

# Making the bars
ggplot() + 
  geom_bar(data = subset(data, year %in% c("2019", "2018")), aes(x=week, y=freq, fill = year),       
  stat= "identity", position=position_dodge()) + 
   # I need the keys for bars in the legend
  scale_fill_manual(name = "", 
                    values = c("2019" = "deepskyblue", "2018" = "coral1"), 
                    labels = c("2019 enrollment", "2018 enrollment")) + 

  # This is the line that I need to be included in legend, for 2017
  geom_line(data = subset(data, year=="2017"), aes(x=week, y=freq), color = "black",           
  show.legend = FALSE ,size = 2) + 

  # Here I have the geom_line for 2015-2016 years
  # Here I have two problems, first, I am missing one series, and second these two
  # should not be included in the legend
  geom_line(data = subset(data, year %in% c("2016", "2015")), aes(x=week, y=freq, color="year"), 
            show.legend = FALSE, alpha = 0.4, size = 1.5) + 

  # adding some other details that are not important actually for my question
  scale_y_continuous(breaks = seq(0, 75,10), labels =seq(0,70,10)) +
  scale_x_continuous(breaks = seq(0, 53,1), labels =seq(0,53,1) ) +
  theme(axis.line = element_line(color = "black"),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        axis.text.x  = element_text(colour="black", size = 12, face = "bold"),
        axis.text.y  = element_text(colour="black", size = 12, face = "bold"),
        axis.title.x = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 20, r = 0, b = 20, l = 0)),
        axis.title.y = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 0, r = 20, b = 0, l = 0)),
        plot.title   = element_text(colour="black", size = 22, face = "bold", hjust=0.5),
        legend.title = element_blank(),
        legend.text  = element_text(colour="black", size = 18, face = "bold"),
        legend.position = c(0.5, 0.98),
        legend.direction = "horizontal") +
  labs(title = "Title",x = "weeks",y = "number")

Plot using code v1

A second option is going line by line, using geom_line for each series of interest, but still I do not know how to add the 2017 series only to the legend. Below my code for that option:

# bar plot
ggplot() + 
  geom_bar(data = subset(data, year %in% c("2019", "2018")), aes(x=week, y=freq, fill = year), stat= "identity", position=position_dodge()) + 
  scale_fill_manual(name = "", 
                    values = c("2019" = "deepskyblue", "2018" = "coral1"), 
                    labels = c("2019 enrollment", "2018 enrollment")) + 
# Year 2017- I need the key for this one in legend  
  geom_line(data = subset(data, year=="2017"), aes(x=week, y=freq), color = "black", show.legend = TRUE ,size = 2) + 

# Year 2016- I don't need it in legend 
  geom_line(data = subset(data, year=="2016"), aes(x=week, y=freq), color = "green", show.legend = FALSE ,size = 2) +

# Year 2015- I don't need it in legend 
  geom_line(data = subset(data, year=="2015"), aes(x=week, y=freq), color = "red", show.legend = FALSE ,size = 2) +
# additional details not important to the question that I have 
  scale_y_continuous(breaks = seq(0, 110,10), labels =seq(0,110,10)) +
  scale_x_continuous(breaks = seq(0, 53,1), labels =seq(0,53,1) ) +
  theme(axis.line = element_line(color = "black"),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        axis.text.x  = element_text(colour="black", size = 12, face = "bold"),
        axis.text.y  = element_text(colour="black", size = 12, face = "bold"),
        axis.title.x = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 20, r = 0, b = 20, l = 0)),
        axis.title.y = element_text(colour="black", size = 14, face = "bold", hjust=0.5, margin = margin(t = 0, r = 20, b = 0, l = 0)),
        plot.title   = element_text(colour="black", size = 22, face = "bold", hjust=0.5),
        legend.title = element_blank(),
        legend.text  = element_text(colour="black", size = 18, face = "bold"),
        legend.position = c(0.5, 0.98),
        legend.direction = "horizontal") +
  labs(title = "Title",x = "weeks",y = "number")

Plot using code V2

Huge thanks for the help!

Brenda Carolina
  • 127
  • 1
  • 8

1 Answers1

0

A possible solution will be to use new_scale_color function from ggnewscale package to differentiate the plotting of 2015 / 2016 lines with the plotting of 2017 line.

Briefly, you can plot first lines for 2015 and 2016 with the option show.legend = FALSE, set their color with scale_color_manual. then pass new_scale_color function, plot the 2017 line, and set the appropriate attribute for this color.

Altogether, your code can be something like that:

library(ggnewscale)
library(ggplot2)

ggplot(data, aes(x = week, y = freq))+
  geom_col(position = position_dodge(), aes(fill = year), color = NA, data = subset(data, year %in% 2018:2019))+
  scale_fill_manual(name = "", 
                    values = c("2019" = "deepskyblue", "2018" = "coral1"), 
                    labels = c("2019 enrollment", "2018 enrollment")) +
  geom_line(data = subset(data, year %in% 2015:2016), aes(group = year, color = year), show.legend = FALSE)+
  scale_color_manual(name = "", values = c("2015" = "red","2016" = "green"))+
  new_scale_color()+
  geom_line(data = subset(data, year == 2017), aes(group = year, color = year))+
  scale_color_manual(name = "", values = "black", label = "2017 enrollement")+
  scale_y_continuous(breaks = seq(0, 110,10), labels =seq(0,110,10)) +
  scale_x_continuous(breaks = seq(0, 53,1), labels =seq(0,53,1) ) +
  theme(axis.line = element_line(color = "black"),
        axis.text.x = element_text(angle = 60, hjust = 1),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        legend.title = element_blank(),
        legend.text  = element_text(colour="black", size = 10, face = "bold"),
        legend.position = "top",
        legend.direction = "horizontal",
        plot.title   = element_text(colour="black", size = 10, face = "bold", hjust=0.5)) +
  labs(title = "Title",x = "weeks",y = "number")

enter image description here

Does it look what you are trying to achieve ?

dc37
  • 15,840
  • 4
  • 15
  • 32