1

I would like to join the line ("Curva de rarefação") and ribbon ("Desvio-padrão") legends.

hh <- data.frame(rr = sp5$richness, rc = sp1$richness, p = sp5$individuals, sd = sp5$sd)

ggplot(hh)+
  geom_line(aes(x = p, y = rr, color = "rr")) +
  geom_ribbon(aes(x = p, ymin = rr-sd*2, ymax = rr+sd*2, fill = "sd"), alpha = 0.2)+
  geom_line(aes(x = p, y = rc, color = "rc")) +
  theme_minimal()+
  scale_colour_manual("", 
                      breaks = c("rr", "rc"),
                      labels = c("Curva de rarefação", "Curva do coletor"),
                      values = c("black", "red")) +
  scale_fill_manual("",
                      breaks = "sd", labels = "Desvio-padrão", values = "grey") +
  xlab("\nIndivíduos")+
  ylab("Riqueza\n")

enter image description here

Igor Cobelo
  • 419
  • 3
  • 12
  • What do you mean by "combined"? Do you want one legend, where the legend keys for the ribbon and the black line are merged? Or do you want two legends, one with a single red line and one with a black line and a grey filled box? – stefan Oct 13 '20 at 20:43
  • Yes, the second option! Two legends, one with a single red line and one with a black line and a grey filled box. – Igor Cobelo Oct 13 '20 at 20:55

1 Answers1

1

This is quite of a hack. Not sure whether there is an easier way to achieve your desired result but at least it works. (Actually I hoped that you want the first and easy option I offered in my comment (;)

First. There is no kind of a legend for a geom, a legend shows the scale of an aesthetic, i.e. different fills, colors, linetypes, ...

Hence, the first step to achieve your desired result is to use the same aesthetics for both the "black" geom_line and the geom_ribbon but a different aesthetic for the "red" geom_line.

  1. Therefore I use the color and fill aes in geom_line and the geom_ribbon, while for the second geom_line I use linetype. This way we get one legend (actually we get two) for the "black line" and the "ribbon" and a second one for the "red line".

  2. To merge the color and the fill legend we have to set the same name for both legends, which I do via labs(fill = NULL, color = NULL, linetype = NULL) which gets me rid of the legend titles.

  3. Next we set the colors and fill colors as well as the labels via scale_xxx_manual.

  4. After these steps we are almost there, except for the black border around the legend key for the black line. This is the really tricky part, but with some trial and error I figured out that this can be achievd by setting the key_glyph for geom_ribbon to "rect".

  5. Finally I changed the order of the legends so that the "double" legend is shown up first.

Using some random example data check this out:

library(ggplot2)

set.seed(42)

hh <- data.frame(rr = (1:10) + runif(10), rc = (1:10) + runif(10), p = 1:10, sd = runif(10))

labels <- c(rr = "Curva de rarefacao", sd = "Desvio-padrao")
values_fill <- c(rr = "transparent", sd = "grey")
values_color <- c(rr = "black", sd = "transparent")
ggplot(hh)+
  geom_line(aes(x = p, y = rr, color = "rr", fill = "rr")) +
  geom_ribbon(aes(x = p, ymin = rr-sd*2, ymax = rr+sd*2, color = "sd", fill = "sd"), 
              alpha = .2, key_glyph = "rect") +
  geom_line(aes(x = p, y = rc, linetype = "rc"), color = "red") +
  scale_fill_manual(labels = labels, values = values_fill) +
  scale_colour_manual(labels = labels, values = values_color) +
  scale_linetype_discrete(labels = c(rc = "Curva do coletor")) +
  guides(linetype = guide_legend(order = 2), fill = guide_legend(order = 1), color = guide_legend(order = 1)) +
  labs(fill = NULL, color = NULL, linetype = NULL) +
  theme_minimal()
#> Warning: Ignoring unknown aesthetics: fill

EDIT The second approach I had in mind looks like so. Here I first convert your dataframe to long format so that one geom_line is sufficient to plot the two lines. However, in that case we also get a ribbon for the red line. Therefore I set the fill color for the second ribbon to "transparent" which makes it invisible.

library(ggplot2)
library(tidyr)

set.seed(42)

hh <- data.frame(rr = (1:10) + runif(10), rc = (1:10) + runif(10), p = 1:10, sd = runif(10))

# Convert to long 
hh1 <- hh %>% 
  tidyr::pivot_longer(-c(sd, p)) 

labels <- c(rr = "Curva de rarefacao (Desvio-padrao)", rc = "Curva do coletor")
breaks <- c("rr", "rc")

ggplot(hh1)+
  geom_line(aes(x = p, y = value, color = name)) +
  geom_ribbon(aes(x = p, ymin = value-sd*2, ymax = value+sd*2, fill = name), alpha = 0.2)+
  theme_minimal()+
  scale_colour_manual(breaks = breaks, labels = labels,
                      values = c(rr = "black", rc = "red")) +
  scale_fill_manual(breaks = breaks, labels = labels,
                    values = c(rr = "grey", rc = "transparent")) +
  labs(x = "\nIndividuos", y = "Riqueza\n", color = NULL, fill = NULL)

stefan
  • 90,330
  • 6
  • 25
  • 51
  • I believe that in fact I would like the first option! Sorry for my misunderstanding in English. I would like a box with only the black line and the gray background. Thanks!!! – Igor Cobelo Oct 14 '20 at 14:09
  • 1
    HaHa. At least I learned a lot by figuring out the tricky solution for the second option. I just made an edit to show you how the first option could be achieved. Best S. – stefan Oct 14 '20 at 18:36
  • Hahaha Thanks!! Teaching we always learn too! Taking advantage of the topic, would you know how to remove this other question about legend? https://stackoverflow.com/questions/64226907/how-to-customize-legend-in-ggplot-for-multiple-layers-in-a-map?noredirect=1#comment113647388_64226907 – Igor Cobelo Oct 14 '20 at 23:00