/
plot_grid.Rmd
144 lines (118 loc) · 7 KB
/
plot_grid.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
---
title: "Arranging plots in a grid"
author: "Claus O. Wilke"
date: "`r Sys.Date()`"
output:
rmarkdown::html_vignette:
fig_width: 4
vignette: >
%\VignetteIndexEntry{Arranging plots in a grid}
%\VignetteEngine{knitr::rmarkdown}
%\usepackage[utf8]{inputenc}
---
# Basic use of `plot_grid()`
The `plot_grid()` function provides a simple interface for arranging plots into a grid and adding labels to them:
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
require(cowplot)
theme_set(theme_cowplot(font_size=12)) # reduce default font size
plot.mpg <- ggplot(mpg, aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_point(size=2.5)
plot.diamonds <- ggplot(diamonds, aes(clarity, fill = cut)) + geom_bar() +
theme(axis.text.x = element_text(angle=70, vjust=0.5))
plot_grid(plot.mpg, plot.diamonds, labels = c('A', 'B'))
```
If you specify the labels as `labels="AUTO"` or `labels="auto"` then labels will be auto-generated in upper or lower case, respectively:
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
plot_grid(plot.mpg, plot.diamonds, labels = "AUTO")
```
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
plot_grid(plot.mpg, plot.diamonds, labels = "auto")
```
By default, the plots are not aligned, but in many cases they can be aligned via the `align` option:
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
plot_grid(plot.mpg, plot.diamonds, labels = "AUTO", align = 'h')
```
```{r, message=FALSE, fig.width=3.9, fig.height=5.1}
plot_grid(plot.mpg, plot.diamonds, labels = "AUTO", ncol = 1, align = 'v')
```
For more complex combinations of plots that don't have the same number of visual elements, alignment becomes more tricky. In those cases, you also have to specify the margin along which you want to align, via the `axis` option. For example, to align a faceted and a non-faceted plot such that the left axes are aligned, we can use the following:
```{r, message=FALSE, fig.width=5, fig.height=5}
plot.iris <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_point() + facet_grid(. ~ Species) + stat_smooth(method = "lm") +
background_grid(major = 'y', minor = "none") + # add thin horizontal lines
panel_border() # and a border around each panel
plot_grid(plot.iris, plot.mpg, labels = "AUTO", ncol = 1,
align = 'v', axis = 'l') # aligning vertically along the left axis
```
# Supported plot formats
The function `plot_grid()` can handle several different plot formats, including the classes `ggplot` (created by the `ggplot` function), `gtable` (created from `ggplot` or from other grid graphics objects such as `grob` and `gTree` objects) and, if the package **gridGraphics** is installed, `recordedplot` (returned by `recordPlot()`). Since the code to create a `recordedPlot` object would ordinarily create an unwanted plot or file, a function creating a `graphics` based plot (`plot`, `image`, ...) can be passed as well.
For example, the following creates a `recordedPlot` object by recording a previous plot (`plot(sqrt)`):
```{r, message=FALSE, results="hold", collapse=TRUE}
par(bg = "transparent", # switch off background to avoid obscuring adjacent plots
mar = c(3, 3, 1, 1) + .1, # reduce margins
mgp = c(2, 1, 0) # move axis labels closer to axis
)
plot(sqrt) # plot the square root function
recordedplot <- recordPlot() # record the previous plot
```
Next we define a function that creates a plot:
```{r, message=FALSE}
# define the function
plotfunc <- function() {
par(bg = "transparent", # switch off background to avoid obscuring adjacent plots
mar = c(3, 3, 1, 1) + .1, # reduce margins
mgp = c(2, 1, 0) # move axis labels closer to axis
)
image(volcano)
}
plotfunc() # call the function to make the plot
```
And finally a plot (a circle) drawn directly with grid:
```{r, message=FALSE}
gcircle <- grid::circleGrob()
ggdraw(gcircle)
```
Now we combine all these plots with `plot_grid()`:
```{r, message=FALSE, fig.width=7, fig.height=5}
plot_grid(plot.mpg, recordedplot, plotfunc, gcircle, labels = "AUTO", hjust = 0, vjust = 1,
scale = c(1., 1., 1., 0.9))
```
Note that the various alignment functions of `plot_grid()` only work with plots generated by `ggplot`, not with any of the other supported plot types.
# Fine-tuning the plot appearance
You can adjust the label size via the `label_size` option. Default is 14, so larger values will make the labels larger and smaller values will make them smaller:
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
plot_grid(plot.mpg, plot.diamonds, labels = "AUTO", align = 'h', label_size = 12)
```
You can also adjust the font family, font face, and color of the labels:
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
plot_grid(plot.mpg, plot.diamonds, labels = "AUTO", align = 'h', label_fontfamily = "serif",
label_fontface = "plain", label_colour = "blue")
```
Labels can be moved via the `label_x` and `label_y` arguments, and justified via the `hjust` and `vjust` arguments. For example, to place labels into the bottom left corner, you can write:
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
plot_grid(plot.mpg, plot.diamonds, labels = "AUTO", align = 'h', label_size = 12,
label_x = 0, label_y = 0, hjust = -0.5, vjust = -0.5 )
```
It is possible to adjust individual labels one by one by passing vectors of adjustment values to the options `label_x`, `label_y`, `hjust`, and `vjust` (example not shown).
You can also adjust the relative widths and heights of rows and columns:
```{r, message=FALSE, fig.width=6.8, fig.height=2.55}
plot_grid(plot.mpg, plot.diamonds, labels = "AUTO", align = 'h', rel_widths = c(1, 1.3))
```
# Nested plot grids
If you want to generate a plot arrangement that is not a simple grid, you may insert one `plot_grid()` plot into another:
```{r, message=FALSE, fig.width=7.65, fig.height=5.1}
bottom_row <- plot_grid(plot.mpg, plot.diamonds, labels = c('B', 'C'), align = 'h', rel_widths = c(1, 1.3))
plot_grid(plot.iris, bottom_row, labels = c('A', ''), ncol = 1, rel_heights = c(1, 1.2))
```
(Notice how we used `rel_heights` to make to bottom row higher than the top row. Also, we can't auto-generate the labels in this case.)
Alignment is a bit tricky in this case. However, it can be achieved using the `align_plots()` function. The trick is to first align the top-row plot (`plot.iris`) and the first botton-row plot (`plot.mpg`) vertically along the left axis, using the `align_plots()` function. Then these aligned plots can be passed to `plot_grid()`. Note that this vertical alignment does not interfere with the horizontal alignment of the bottom row.
```{r, message=FALSE, fig.width=7.65, fig.height=5.1}
# first align the top-row plot (plot.iris) with the left-most plot of the
# bottom row (plot.mpg)
plots <- align_plots(plot.mpg, plot.iris, align = 'v', axis = 'l')
# then build the bottom row
bottom_row <- plot_grid(plots[[1]], plot.diamonds,
labels = c('B', 'C'), align = 'h', rel_widths = c(1, 1.3))
# then combine with the top row for final plot
plot_grid(plots[[2]], bottom_row, labels = c('A', ''), ncol = 1, rel_heights = c(1, 1.2))
```