-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPlotInPlot.Rmd
87 lines (66 loc) · 3.56 KB
/
PlotInPlot.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
---
title: 'Plots within Plots'
output:
html_document:
highlight: pygments
theme: spacelab
toc: yes
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r echo=FALSE, warning=FALSE, message=FALSE}
if(!require(easypackages)){install.packages("easypackages")}
library(easypackages)
packages("tidyverse", "ggmap", "grid", prompt = FALSE)
```
# Plots within plots with ggplot2 and ggmap
Once in a while, you might find yourself wanting to embed one plot within another plot. ggplot2 makes this really easy with the annotation_custom function. The following example illustrates how you can achieve this. (For all the code in one R file, click here.)
Let’s generate some random data and make a scatterplot along with a smoothed estimate of the relationship:
```{r message=FALSE}
set.seed(42)
n <- 1000
x <- runif(n) * 3
y <- x * sin(1/x) + rnorm(n) / 25
df <- data.frame(x = x, y = y)
p1 <- ggplot(df, aes(x, y)) + geom_point(alpha = 0.3) + geom_smooth(se = FALSE) + theme_bw()
p1
```
The smoother seems to be doing a good job of capturing the relationship for most of the plot, but it looks like there’s something more going on in the x \in [0, 0.5] region. Let’s zoom in:
```{r message=FALSE, warning=FALSE}
p2 <- ggplot(df, aes(x, y)) + geom_point(alpha = 0.3) + geom_smooth(se = FALSE) +
scale_x_continuous(limits = c(0, 0.5)) + scale_y_continuous(limits = c(-0.3, 0.6)) + theme_bw()
p2
```
That certainly seems like a meaningful relationship! While we might want to plot p1 to depict the overall relationship, it is probably a good idea to show p2 as well. This can be achieved very easily:
```{r}
p1 + annotation_custom(ggplotGrob(p2), xmin = 1, xmax = 3, ymin = -0.3, ymax = 0.6)
```
The first argument is for `annotation_custom` must be a “grob” which we can create using the `ggplotGrob` function. The 4 other arguments (`xmin` etc.) indicate the coordinate limits for the inset: __these coordinates are with reference to the axes of the outer plot__. The inset will try to fill up the space indicated by these 4 arguments while being center-justified.
For `ggmap` objects, need to use `inset` instead of `annotation_custom.` This will be illustrated by making a map of continental USA with insets for Alaska and Hawaii.
Get a map of continental US:
```{r}
us_bbox <- c(left = -125, bottom = 25, right = -55, top = 50)
us_main_map <- ggmap::get_stamenmap(us_bbox, zoom = 5, maptype = "terrain")
p_main <- ggmap::ggmap(us_main_map)
p_main
```
Get maps for Alaska and Hawaii and save them into R variables. Each plot will have a title for the state, and information on the axes will be removed.
```{r}
alaska_bbox <- c(left = -180, bottom = 50, right = -128, top = 72)
alaska_map <- ggmap::get_stamenmap(alaska_bbox, zoom = 5, maptype = "terrain")
p_alaska <- ggmap::ggmap(alaska_map) + labs(title = "Alaska") +
theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank())
p_alaska
hawaii_bbox <- c(left = -160, bottom = 18.5, right = -154.5, top = 22.5)
hawaii_map <- ggmap::get_stamenmap(hawaii_bbox, zoom = 6, maptype = "terrain")
p_hawaii <- ggmap::ggmap(hawaii_map) + labs(title = "Hawaii") +
theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank())
p_hawaii
```
Use `inset` twice to embed these two plots (fiddle around with the `xmin` etc. options to get it to come out right):
```{r}
p_main +
inset(ggplot2::ggplotGrob(p_alaska), xmin = -76.7, xmax = -66.7, ymin = 26, ymax = 35) +
inset(ggplot2::ggplotGrob(p_hawaii), xmin = -66.5, xmax = -55.5, ymin = 26, ymax = 35)
```