sometimes 2 legends, sometimes combined into 1, depending on geom_... order and input data. Why?

i would like to make line plot with a ribbon highlighting part of one of the lines. I want the ribbon drawn "behind" the lines, so the lines do not appear faded where the ribbon is drawn. I want one legend.
I can get one legend with warnings in my log, or one legend with the ribbon drawn over the lines, or one legend if I just show two lines. If I draw the ribbon first (i.e., under the lines), and have more than 2 lines, I get two legends. My questions: 1) Can I draw what I would like (above) without warnings? 2) Can someone explain what drives this legend behavior I see, so I can work with it better?

Here is a simplified example:

library("tidyverse")
myOrange <- ( # add ymin and ymax values to tree "1" records where age > 1200
  Orange 
  %>% filter(Tree %in% c("1", "4", "5")) # if I leave out "5", I get just one legend in the 1st graph!
  %>% mutate(ymax=ifelse(Tree=="1" & age>1200, circumference+10, NA)
             , ymin=ifelse(Tree=="1" & age>1200, circumference-10, NA))
)
( #1 Put geom_ribbon with filtered data BEFORE geom_line: 2 legends, apparently split because the geom_ribbon does not use the full ggplot data frame
  ggplot(data=myOrange,aes(x=age, y=circumference, color=Tree, ymin=ymin, ymax=ymax, fill=Tree))
  + geom_ribbon(alpha = .75, color = NA, data=. %>% filter(Tree=="1"))
  + geom_line()
  + scale_fill_manual(values=c("1"="pink", "2"=NA, "3"=NA, "4"=NA, "5"=NA))
)

( #2 Put geom_ribbon with all data BEFORE geom_line: one legend, 2 warnings (because ymin and ymax are all NA for trees "4" and "5")
  ggplot(data=myOrange,aes(x=age, y=circumference, color=Tree, ymin=ymin, ymax=ymax, fill=Tree))
  + geom_ribbon(alpha = .75, color = NA)#, data=. %>% filter(Tree=="1"))
  + geom_line()
  + scale_fill_manual(values=c("1"="pink", "2"=NA, "3"=NA, "4"=NA, "5"=NA))
)
#> Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning -
#> Inf

#> Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning -
#> Inf

( #3 Put geom_ribbon AFTER geom_line: one legend, but ribbon drawn on top of lines
  ggplot(data=myOrange,aes(x=age, y=circumference, color=Tree, ymin=ymin, ymax=ymax, fill=Tree))
  + geom_line()
  + geom_ribbon(alpha = .75, color = NA, data=. %>% filter(Tree=="1"))
  + scale_fill_manual(values=c("1"="pink", "2"=NA, "3"=NA, "4"=NA, "5"=NA))
)

( #4 Like #1, but limit input to TWO trees: 1 legend, ribbon drawn behind the lines (as I want), but, of course it is missing other lines that I want. 
  ggplot(data=myOrange %>% filter(Tree %in% c("1", "5")), aes(x=age, y=circumference, color=Tree, ymin=ymin, ymax=ymax, fill=Tree))
  + geom_ribbon(alpha = .75, color = NA, data=. %>% filter(Tree=="1"))
  + geom_line()
  + scale_fill_manual(values=c("1"="pink", "2"=NA, "3"=NA, "4"=NA, "5"=NA))
)

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

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

If you have a query related to it or one of the replies, start a new topic and refer back with a link.