-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy path09-Arranging_plots.Rmd
331 lines (243 loc) · 8.66 KB
/
09-Arranging_plots.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# Arranging Plots
**Learning Objectives**
1. Produce several subplots as part of the same main visualization
2. Understand how to arrange plots
- in rows and columns
- on top of each other (insets)
## Introduction {-}
Want to arrange multiple plots; need more than faceting
This chapter discusses {patchwork}.
Others:
* {cowplot}
* {gridExtra}
* {ggpubr}
## Arranging plots side by side with no overlap {-}
```{r 09-library, message=FALSE, warning=FALSE, include=FALSE, paged.print=FALSE}
library(tidyverse)
```
Let's imagine we have several plots:
```{r 09-dataplots}
p1 <- ggplot(mpg) +
geom_point(aes(x = displ, y = hwy))
p2 <- ggplot(mpg) +
geom_bar(aes(x = as.character(year), fill = drv), position = "dodge") +
labs(x = "year")
p3 <- ggplot(mpg) +
geom_density(aes(x = hwy, fill = drv), colour = NA) +
facet_grid(rows = vars(drv))
p4 <- ggplot(mpg) +
stat_summary(aes(x = drv, y = hwy, fill = drv), geom = "col", fun.data = mean_se) +
stat_summary(aes(x = drv, y = hwy), geom = "errorbar", fun.data = mean_se, width = 0.5)
```
```{r 09-plot1}
library(patchwork)
p1 + p2 # same as p1 | p2
```
```{r 09-plot2}
p1 + p2 + p3 + p4
```
## Controlling the layout {-}
```{r 09-plot3}
p1 + p2 + p3 + plot_layout(ncol = 2)
```
```{r 09-plot4}
p1 / p2
```
## More compositions: {-}
```{r 09-plot5}
p3 | (p2 / (p1 | p4))
```
## Layouts can get creative! {-}
```{r 09-plot6}
layout <- "
AAB
C#B
CDD
"
p1 + p2 + p3 + p4 + plot_layout(design = layout)
```
## Collect repeats of the same legend {-}
```{r 09-plot7}
p1 + p2 + p3 + guide_area() + plot_layout(ncol = 2, guides = "collect")
```
## Parts of the patchwork object can still be modified {-}
```{r 09-plot8}
p12 <- p1 + p2
p12[[1]] <- p12[[1]] + theme_light()
p12
```
## New operator: `&` adds whole-plot themes {-}
```{r 09-plot9}
p1 + p4 &
scale_y_continuous(limits = c(0, 45)) &
theme_minimal()
```
### Plot annotations {-}
```{r 09-plot10}
p34 <- p3 + p4 +
plot_annotation(
title = "A closer look at the effect of drive train in cars",
caption = "Source: mpg dataset in ggplot2",
tag_levels = "I") &
theme_gray(base_family = "mono")
p34
```
## Labeling plots (e.g. parts of figures) {-}
```{r 09-plot11}
new <- p34
keep <- p34
new[[2]] <- new[[2]] + plot_layout(tag_level = "new")
keep[[2]] <- keep[[2]] + plot_layout(tag_level = "keep")
```
```{r}
new
```
```{r}
keep
```
## Specify the type of tags/labels {-}
```{r}
p34 + plot_annotation(tag_levels = c("I", "a"))
```
## Arranging plots on top of each other {-}
Instead of putting plots next to or above/below each other, we can nest them.
General options: left, right, top, and bottom.
Set specific locations
- `grid::unit()`--npc units ("Normalized Parent Coordinates"), ranges from 0 to 1
Location is relative to **panel area**, not **plot area**. `align_to` arg changes this.
## Example: {-}
Placing an inset exactly 15 mm from the top right corner:
```{r 09-plot12}
p1 +
inset_element(
p2,
left = 0.4,
bottom = 0.4,
right = unit(1, "npc") - unit(15, "mm"),
top = unit(1, "npc") - unit(15, "mm"),
align_to = "full"
)
```
## Another inset example with annotation {-}
```{r 09-plot13}
p24 <- p2 / p4 + plot_layout(guides = "collect")
p1 +
inset_element(p24, left = 0.5, bottom = 0.05, right = 0.95, top = 0.9) +
plot_annotation(tag_levels = 'A') &
theme_bw()
```
## Extra {-}
**grid and gridExtra packages**
```{r 09-plot14, message=FALSE, warning=FALSE, paged.print=FALSE}
library(gridExtra)
library(grid)
grid.arrange(p1, p2, p3, p4, ncol=2)
```
**cowplot package**
```{r 09-plot15, message=FALSE, warning=FALSE, paged.print=FALSE}
library(cowplot)
plot_grid(p1, p2,
labels = c('A', 'B'),
align = "h",
label_size = 12,
label_fontfamily = "serif",
label_fontface = "plain",
label_colour = "blue",
rel_widths = c(1, 2))
```
```{r 09-plot16, message=FALSE, warning=FALSE, paged.print=FALSE}
# We saved this to the images folder already.
# ggsave("images/p1.png", p1)
ggdraw()+
draw_plot(p3)+
draw_image("images/p1.png",x=0.4,y=0.4,scale=0.5)+
draw_label("This is some text",x=0.5,y=0.9)
```
To add a common title we use `ggdraw()
```{r 09-plot17}
plot_row <- plot_grid(p1, p2)
# now add the title
title <- ggdraw() +
draw_label("Common title",
fontface = 'bold', x = 0, hjust = 0) +
theme(plot.margin = margin(0, 0, 0, 7))
plot_grid(title, plot_row,
ncol = 1,
rel_heights = c(0.1, 1))
```
```{r 09-plot18}
ggdraw()+
draw_plot(p1,x=0.1,y=0,scale=0.5)+
draw_plot(p2,x=-0.2,y=0,scale=0.5)+
draw_label("This plot is made with cowplot",
x=0.5,y=0.95,
color="pink",
fontface="bold",size=20)
```
**ggpubr package**
```{r 09-plot19, message=FALSE, warning=FALSE, paged.print=FALSE}
library(ggpubr)
ggarrange(p1, p2, p3, ncol = 2, nrow = 2,common.legend = TRUE)
```
## Conclusions {-}
[Patchwork - imaginist](https://patchwork.data-imaginist.com/) is one of the packages mentioned in the book, also some other packages provide same results with different approaches.
### Extra resources: {-}
- [grid and gridExtra](https://cran.r-project.org/web/packages/gridExtra/vignettes/arrangeGrob.html)
- [cowplot](https://wilkelab.org/cowplot/articles/plot_grid.html)
- [ggpubr](https://rpkgs.datanovia.com/ggpubr/reference/ggarrange.html)
## Meeting Videos {-}
### Cohort 1 {-}
`r knitr::include_url("https://www.youtube.com/embed/mGE639JpneE")`
<details>
<summary> Meeting chat log </summary>
```
00:27:47 Lydia Gibson: What are npc unts?
00:27:56 Michael Haugen: "npc" (Normalized Parent Coordinates)
00:28:02 Michael Haugen: 0 to 1
00:28:07 Lydia Gibson: Oh okay. Thank you!
00:28:16 Michael Haugen: Same thing that was used for faceting annotations.
00:28:43 Michael Haugen: so .8 is l80 percent of the way up the y axis for example.
00:28:47 Lydia Gibson: I missed annotations last week. I’ll have to go back and watch the session.
00:43:21 SriRam: I use patch and cowplot
00:50:00 Kent Johnson: https://www.cedricscherer.com/2019/08/05/a-ggplot2-tutorial-for-beautiful-plotting-in-r/
00:50:09 Lydia Gibson: Thank you!
00:50:17 Michael Haugen: The arrows are in chapter 8.3 with geom and curve for example, annotate(
geom = "curve", x = 4, y = 35, xend = 2.65, yend = 27,
curvature = .3, arrow = arrow(length = unit(2, "mm"))
) +
00:51:16 Michael Haugen: and arrows came up in the discussion as a discussion of the GROB and arrows and how to render your plot so the arrows are not distorted.
00:51:16 Ryan Metcalf: Perfect! “arrow” was the argument I was after!
00:51:37 Michael Haugen: And then we talked about ggsave as a part of that
00:53:32 Michael Haugen: we all will be at Cedric’s level by the end of this bookclub right?
00:53:47 SriRam: :D
00:53:52 Lydia Gibson: Hopefully lol
00:54:20 Ryan S: Thank you!
00:54:29 SriRam: Thank you
```
</details>
`r knitr::include_url("https://www.youtube.com/embed/lxkk5MCWREQ")`
<details>
<summary> Meeting chat log </summary>
```
00:04:54 June Choe: https://yjunechoe.github.io/ggtrace-talk/
00:12:16 Ryan S: brilliant... didn't know this before but really simplifies the concept
00:14:08 Michael Haugen: Makes sense
00:26:15 June Choe: https://ggplot2.tidyverse.org/reference/aes_eval.html
00:26:36 Ryan Metcalf: I’m thinking in the context….I buy a car. The engineers have optimized it for longevity….but I want a hot rod….So I need to open the hood and change parts. Or, access the computer and start changing parameters.
00:32:54 SriRam: This is like scuba diving, more beautiful under the surface :)
00:33:15 Stan Piotrowski: Great analogy, SriRam!
00:33:17 Ryan Metcalf: Completely agree @SriRam!
00:36:44 June Choe: ggplot2:::ggplot_build.ggplot
00:37:58 June Choe: ggplot2:::print.ggplot
00:50:22 Federica Gazzelloni: thanks June!!!
00:50:54 SriRam: Out of curiosity, how much of this trickery (internal functions) can be learnt from "advanced R" or are these mentioned in the ggplot book ? I am just a regular user, I may not go this deep, but looks very interesting to explore/read during the Christmas break
00:51:12 Stan Piotrowski: I’m in the same boat as SriRam
00:51:32 Stan Piotrowski: Curious to know more about this but can definitely see myself getting lost in a rabbit hole
00:54:23 Ryan S: at some point -- maybe a different session -- can we dive deep into the different stat options ("identity", "count", etc.)
00:54:47 Ryan S: specifically, what do they do and when would you use them
00:55:09 Ryan Metcalf: June, this is amazing!
00:57:27 SriRam: Countdown starts...... 5 mins to come back to reality !!! :D
01:02:21 Stan Piotrowski: Great talk, June!
01:02:34 Kent Johnson: Thank you! See you next week!
```
</details>