0

For my rmarkdown document, I've put together two plots. The second plot is supposed to be a "zoomed in" version of the first plot.

---
title: TwoGraphs
output: pdf_document
---

```{r echo=FALSE,fig.show="hold", out.width="50%",fig.cap="Results"}
library(ggplot2)
data <- data.frame(
  a_max = 1:10 * 10,
  a_min = 1:10 * 9,
  b_max = 1:10 * 5,
  b_min = 1:10 * 4,
  c_max = 1:10 * 0.002,
  c_min = 1:10 * 0.001
)

ggplot(data, aes(x = 1:10)) +
  xlab("Time") + ylab("Amount") +
  # a
  geom_ribbon(aes(ymax = a_max, ymin = a_min, fill = "A set"), fill = '#9B7FBF') +
  geom_line(aes(y = a_max), color = "#1e152a", size=1.5, linetype="dashed") +
  geom_line(aes(y = a_min), color = "#1e152a", size=1.5) +
  # b
  geom_ribbon(aes(ymax = b_max, ymin = b_min, fill = "B set"), fill = '#ACD8DD') +
  geom_line(aes(y = b_max), color = "#5ab1bb", size=1.5, linetype="dashed") +
  geom_line(aes(y = b_min), color = "#5ab1bb", size=1.5) +
  # c
  geom_ribbon(aes(ymax = c_max, ymin = c_min, fill = "C set"), fill = '#deebd1') +
  geom_line(aes(y = c_max), color = "#a5c882", size=1.5, linetype="dashed") +
  geom_line(aes(y = c_min), color = "#a5c882", size=1.5) +
  theme_bw()

# zoom in on c
ggplot(data, aes(x = 1:10)) +
  xlab("Time") + ylab("Amount") +
  geom_ribbon(aes(ymax = c_max, ymin = c_min, fill = "C set"), fill = '#deebd1') +
  geom_line(aes(y = c_max), color = "#a5c882", size=1.5, linetype="dashed") +
  geom_line(aes(y = c_min), color = "#a5c882", size=1.5) +
  theme_bw()
```

Generating the plot works fine, however the legend I want to have is missing. Particularly I want the ribbon colors to be notated. The lines are not so important - I do mention in the caption though that dashed means most unsorted dataset, and a continuous line means that the dataset is sorted.

I have marked the legend I want to have in the screenshot below.

Two plots, below I drew in the legends I want to have

From this answer I have tried working adding scale_fill_manual, but it didn't show the legend. Using ggpubr as suggested here also didn't work for me, as demonstrated here.

---
title: TwoGraphs
output: pdf_document
---

```{r echo=FALSE,fig.show="hold", out.width="50%",fig.cap="Results"}
library(ggplot2)
data <- data.frame(
  a_max = 1:10 * 10,
  a_min = 1:10 * 9,
  b_max = 1:10 * 5,
  b_min = 1:10 * 4,
  c_max = 1:10 * 0.002,
  c_min = 1:10 * 0.001
)

p1 <- ggplot(data, aes(x = 1:10)) +
  xlab("Time") + ylab("Amount") +
  # a
  geom_ribbon(aes(ymax = a_max, ymin = a_min, fill = "Aha"), fill = '#9B7FBF') +
  geom_line(aes(y = a_max), color = "#1e152a", size=1.5, linetype="dashed") +
  geom_line(aes(y = a_min), color = "#1e152a", size=1.5) +
  # b
  geom_ribbon(aes(ymax = b_max, ymin = b_min, fill = "Behe"), fill = '#ACD8DD') +
  geom_line(aes(y = b_max), color = "#5ab1bb", size=1.5, linetype="dashed") +
  geom_line(aes(y = b_min), color = "#5ab1bb", size=1.5) +
  # c
  geom_ribbon(aes(ymax = c_max, ymin = c_min, fill = "Cehe"), fill = '#deebd1') +
  geom_line(aes(y = c_max), color = "#a5c882", size=1.5, linetype="dashed") +
  geom_line(aes(y = c_min), color = "#a5c882", size=1.5) +
  theme_bw()

p2 <- ggplot(data, aes(x = 1:10)) +
  xlab("Time") + ylab("Amount") +
  geom_ribbon(aes(ymax = c_max, ymin = c_min, fill = "Cehe"), fill = '#deebd1') +
  geom_line(aes(y = c_max), color = "#a5c882", size=1.5, linetype="dashed") +
  geom_line(aes(y = c_min), color = "#a5c882", size=1.5) +
  theme_bw()
 
library(ggpubr)

ggarrange(p1,p2,common.legend = TRUE,legend = "bottom")
```

ggpubr also doesn't draw legends

How do I get the three filled areas to show up as a common legend? Is it also possible to add an overarching dashed-line / solid-line legend? (i.e., "dashed = unsorted, solid = sorted")

Felix Jassler
  • 1,029
  • 11
  • 22

1 Answers1

2

When you add a fill colour outside aes, it over-rides the one you put inside. You need to remove these and specify your colours inside scale_fill_manual. You can follow exactly the same process with the linetype aesthetic.

ggplot(data, aes(x = 1:10)) +
  xlab("Time") + ylab("Amount") +
  # a
  geom_ribbon(aes(ymax = a_max, ymin = a_min, fill = "A set")) +
  geom_line(aes(y = a_max, linetype = "sorted"), color = "#1e152a", size=1.5) +
  geom_line(aes(y = a_min, linetype = "unsorted"), color = "#1e152a", size=1.5) +
  # b
  geom_ribbon(aes(ymax = b_max, ymin = b_min, fill = "B set")) +
  geom_line(aes(y = b_max, linetype = "sorted"), color = "#5ab1bb", size=1.5) +
  geom_line(aes(y = b_min, linetype = "unsorted"), color = "#5ab1bb", size=1.5) +
  # c
  geom_ribbon(aes(ymax = c_max, ymin = c_min, fill = "C set")) +
  geom_line(aes(y = c_max, linetype = "sorted"), color = "#a5c882", size=1.5) +
  geom_line(aes(y = c_min, linetype = "unsorted"), color = "#a5c882", size=1.5) +
  theme_bw() +
  scale_fill_manual(values = c(`A set` = '#9B7FBF', `B set` = '#ACD8DD',
                               `C set` = '#deebd1')) +
  scale_linetype_manual(values = c(sorted = 1, unsorted = 2)) +
  guides(linetype = guide_legend(override.aes = list(color = "black", size = 0.4))) +
  labs(fill = "", linetype = "") +
  theme(legend.position = "bottom",
        legend.direction = "vertical")

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • That's already a great solution! I tried incorporating it with `ggpubr`, but now the plots are way too tall. When I try to set `aspect.ratio = 3/4` in `theme`, there appears a lot of whitespace above and below the plots. Setting `legend.margin` or `plot.margin` to `margin()` didn't seem to have an effect. Do you know by any chance how to solve this? – Felix Jassler Apr 03 '22 at 22:41
  • Do you need to adjust `fig.height` in your Rmarkdown chunk? – Allan Cameron Apr 03 '22 at 22:50
  • Ah, setting `fig.height` for the code chunk instead of juggling with aspect ratios did the trick. Thank you very much! – Felix Jassler Apr 03 '22 at 23:00