1

I am trying to plot multiple location data using facet_wrap functionality of ggplot. I am having trouble in creating the legends (95% confidence interval is completely missed). Below is my code and I would appreciate any suggestion.

library(ggplot2)
library(lubridate)

set.seed(123)

DF1 <- data.frame(Date = seq(as.Date("2001-01-01"), to = as.Date("2005-12-31"), by = "1 month"),
                  Ob = runif(60,1,5), L95 =runif(60, 0,4), U95 = runif(60,2,7), Sim = runif(60,1,5),
                  Loc = rep("Upstream", 60))

DF2 <- data.frame(Date = seq(as.Date("2001-01-01"), to = as.Date("2005-12-31"), by = "1 month"),
                  Ob = runif(60,1,5), L95 =runif(60, 0,4), U95 = runif(60,2,7), Sim = runif(60,1,5),
                  Loc = rep("Downstream", 60))

DF <- dplyr::bind_rows(DF1,DF2)

DF$Loc <- factor(DF$Loc, levels = c("Upstream","Downstream"))


ggplot(DF, aes(x = Date))+
  geom_ribbon(aes(ymin = L95, ymax = U95), fill = "grey30", alpha = 0.4)+
  geom_line(aes(y = Ob, color = "blue"), size = 1 )+
  geom_line(aes(y = Sim, color = "black"), size =  1, linetype = "dashed")+
  geom_vline(xintercept = as.Date("2004-12-01"),color = "red", size = 1.30)+
  facet_wrap(~ Loc, ncol = 1, scales = "free_y")+ 
  theme_bw()+
  scale_color_identity(guide = "legend", breaks = c("grey30", "blue", "black"),
                       labels = c("95% confidence bound", "Observation","Simulation"))
Axeman
  • 32,068
  • 8
  • 81
  • 94
Hydro
  • 1,057
  • 12
  • 25

2 Answers2

2

enter image description here

Your fill is outside the aes function, so it cannot appear in the legend.

ggplot(DF, aes(x = Date))+
  geom_ribbon(aes(ymin = L95, ymax = U95, color = "grey30"), fill = "grey30", alpha = 0.4)+
  geom_line(aes(y = Ob, color = "blue"), size = 1 )+
  geom_line(aes(y = Sim, color = "black"), size =  1, linetype = "dashed")+
  geom_vline(xintercept = as.Date("2004-12-01"),color = "red", size = 1.30)+
  facet_wrap(~ Loc, ncol = 1, scales = "free_y")+ 
  theme_bw()+
  scale_color_identity(guide = "legend", breaks = c("grey30", "blue", "black"),
                       labels = c("95% confidence bound", "Observation","Simulation"))
  ggplot(DF, aes(x = Date))+
    geom_ribbon(aes(ymin = L95, ymax = U95, fill = "grey30"), alpha = 0.4)+
    geom_line(aes(y = Ob, color = "blue"), size = 1 )+
    geom_line(aes(y = Sim, color = "black"), size =  1, linetype = "dashed")+
    geom_vline(xintercept = as.Date("2004-12-01"),color = "red", size = 1.30)+
    facet_wrap(~ Loc, ncol = 1, scales = "free_y")+ 
    theme_bw()+
    scale_color_identity(guide = "legend", breaks = c( "blue", "black"),
                         labels = c( "Observation","Simulation"),
                         name = 'Legend')+
    scale_fill_identity(guide = "legend", labels = c("95% confidence bound"), 
                        name=NULL)+
    theme(legend.spacing.y = unit(-0.2, "cm"))+
    theme(legend.title = element_text(margin=margin(b = 0.4, unit='cm')))
Liman
  • 1,270
  • 6
  • 12
  • I am having trouble to remove the box around the legend- i tried `theme(legend.key = element_rect(colour = NA, fill = NA), legend.box.background = element_blank())` but it didn't work- any thought on this? – Hydro Nov 22 '20 at 19:59
  • Not sure I understand! Are you looking for something like https://stackoverflow.com/questions/49373461/removing-the-border-of-legend-symbol/49377292#49377292 ? – Liman Nov 22 '20 at 20:11
  • Yes, but its not working here- not sure why? are you able to remove the boxes around the legend? – Hydro Nov 22 '20 at 20:24
  • 1
    You're right, this doesn't seem to work. see my edits in the answer – Liman Nov 22 '20 at 20:58
  • Thank you @Liman. Is there a way to add annotation to only the first facet? I tried `annotate(geom = "Text", x = as.Date("2000-01-01"), y = 5, label = "Calibration")` but this add the annotation on both facets. – Hydro Nov 23 '20 at 14:03
  • You may need to make a new data with `(x, y, facet)` coordinates of the point where you want the annotation to appear on plot. Try with the following: `geom_text(data = data.frame(Date = as.Date("2002-01-01"), Ob = 6.5, Loc = factor("Upstream", levels = c("Upstream","Downstream"))), aes(Date, Ob), label='Calibration', size = 5)` – Liman Nov 23 '20 at 14:47
1

Here is how I would do this.

First, you are using fill for the ribbon, not color. Second, you need to actually map fill in aes, not just set it outside the aes. Then I would give the names you'd like in the aes calls, and use scale_*_manual to set the values you'd like:

ggplot(DF, aes(x = Date))+
  geom_ribbon(aes(ymin = L95, ymax = U95, fill = "95% confidence bound"), alpha = 0.4)+
  geom_line(aes(y = Ob, color = "Observation"), size = 1 )+
  geom_line(aes(y = Sim, color = "Simulation"), size =  1, linetype = "dashed")+
  geom_vline(xintercept = as.Date("2004-12-01"),color = "red", size = 1.30)+
  facet_wrap(~ Loc, ncol = 1, scales = "free_y")+ 
  theme_bw()+
  scale_color_manual(values = c('blue', 'black'), name = NULL) +
  scale_fill_manual(values = 'grey30', name = NULL)

There are a number of valid ways to approach this, but this is how many people do it.

Axeman
  • 32,068
  • 8
  • 81
  • 94