-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsection_E.Rmd
More file actions
395 lines (282 loc) · 13.3 KB
/
Copy pathsection_E.Rmd
File metadata and controls
395 lines (282 loc) · 13.3 KB
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
---
title: "Section E"
subtitle: "https://dcsuh.github.io/mappingInR/"
author: "Daniel Suh"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r,message=F}
library(sf)
library(terra)
library(tidyverse)
library(spData)
#install.packages("spDataLarge", repos = "https://nowosad.r-universe.dev")
library(spDataLarge)
library(magrittr)
library(tmap) # for static and interactive maps
library(leaflet) # for interactive maps
library(ggplot2) # tidyverse data visualization package
```
## Making Maps with R
Time to make some maps. We'll focus on the 'tmap' package here, but there are a number of packages dedicated to making maps. We'll also introduce 'leaflet' and the mapping capabilites of 'ggplot2'. First, we will go over static maps and then move on to dynamic and interactive maps.
## Static Maps
Static maps are the most common result when visualizing spatial data. Base R's plot() can be used for static maps as we've demonstrated throughout the workshop. However, 'tmap' offers more options for aesthetics and follows a similar syntax with ggplot.
## tmap
Like ggplot, tmap follows a 'grammar of graphics' (the gg in ggplot), where input data is separated from the aesthetics. Input data is defined using tm_shape() and aesthetics are layered on using a wide variety of functions such as tm_fill() and tm_dots().
```{r}
# Add fill layer to nz shape
tm_shape(nz) +
tm_fill()
# Add border layer to nz shape
tm_shape(nz) +
tm_borders()
# Add fill and border layers to nz shape
tm_shape(nz) +
tm_fill() +
tm_borders()
```
Play around with tmap. Type help("tmap-element") into your console for a full list of functions.
## Map objects
A useful feature of tmap is its ability to store objects representing maps.
```{r}
map_nz <- tm_shape(nz) + tm_polygons()
class(map_nz)
```
Storing maps as map objects is useful for adding aesthetic layers and new spatial objects on top of each other. You can now add layers to 'map_nz' by simply using the + operator. If you add + tm_shape() then you can add another spatial object.
```{r}
nz_elev = rast(system.file("raster/nz_elev.tif", package = "spDataLarge"))
map_nz1 = map_nz +
tm_shape(nz_elev) + tm_raster(alpha = 0.7)
```
```{r}
nz_water = st_union(nz) %>% st_buffer(22200) %>%
st_cast(to = "LINESTRING")
map_nz2 = map_nz1 +
tm_shape(nz_water) + tm_lines()
```
```{r}
map_nz3 = map_nz2 +
tm_shape(nz_height) + tm_dots()
```
```{r}
tmap_arrange(map_nz1, map_nz2, map_nz3)
```
## Aesthetics
Like ggplot, the default aesthetics of each layer can be changed. Unlike ggplot, tmap does not use the aes() function but layers can accept arguments that are fixed values or variable fields (based on column names).
Here is an example of fixed values
```{r}
ma1 = tm_shape(nz) + tm_fill(col = "red")
ma2 = tm_shape(nz) + tm_fill(col = "red", alpha = 0.3)
ma3 = tm_shape(nz) + tm_borders(col = "blue")
ma4 = tm_shape(nz) + tm_borders(lwd = 3)
ma5 = tm_shape(nz) + tm_borders(lty = 2)
ma6 = tm_shape(nz) + tm_fill(col = "red", alpha = 0.3) +
tm_borders(col = "blue", lwd = 3, lty = 2)
tmap_arrange(ma1, ma2, ma3, ma4, ma5, ma6)
```
And here is an example of how you would use values from a variable. The argument will take the character string associated with the column you are interested in.
```{r}
tm_shape(nz) + tm_fill(col = "Land_area")
```
Finally, you can add nicer titles. expression() allows for superscripts
```{r}
legend_title = expression("Area (km"^2*")")
map_nza = tm_shape(nz) +
tm_fill(col = "Land_area", title = legend_title) + tm_borders()
map_nza
```
## Color settings
Colors are useful. Here are a few ways to manipulate color in your maps. Play around and figure out what each of these arguments (breaks, n, palette) do.
```{r}
col1 <- tm_shape(nz) + tm_polygons(col = "Median_income")
breaks <- c(0, 3, 4, 5) * 10000
col2 <- tm_shape(nz) + tm_polygons(col = "Median_income", breaks = breaks)
col3 <- tm_shape(nz) + tm_polygons(col = "Median_income", n = 10)
col4 <- tm_shape(nz) + tm_polygons(col = "Median_income", palette = "BuGn")
tmap_arrange(col1, col2, col3, col4)
```
tmap also allows for setting breaks using the style argument rather than manual setting breaks. Try out a few of the different style options: "pretty", "equal", "quantile", "jenks", "cont", "cat"
```{r}
tm_shape(nz) + tm_polygons(col = "Median_income", style = "pretty")
```
Palettes define the color range used and can be critical for interpretability of your figures. Palettes can be categorical, sequential, or diverging and each of these serve different purposes. To adjust the palette, you can use the palette argument in tmap.
```{r}
tm_shape(nz) + tm_polygons("Population", palette = "Blues")
tm_shape(nz) + tm_polygons("Population", palette = "YlOrBr")
```
Please reference section 8.2.4 of the online textbook to learn more about good habits for choosing palettes and when it is appropriate to use each.
## Layouts
The map layout refers to the combination of all map elements into a cohesive map. Map elements include among others the objects to be mapped, the title, the scale bar, margins and aspect ratios.
These additional elements can have their own functions for easy layering onto your maps.
```{r}
map_nz +
tm_compass(type = "8star", position = c("left", "top")) +
tm_scale_bar(breaks = c(0, 100, 200), text.size = 1)
```
tm_layout allows for more customization of layout elements
```{r}
layout1 <- map_nz + tm_layout(title = "New Zealand")
layout2 <- map_nz + tm_layout(scale = 5)
layout3 <- map_nz + tm_layout(bg.color = "lightblue")
layout4 <- map_nz + tm_layout(frame = FALSE)
tmap_arrange(layout1, layout2, layout3, layout4)
```
tmap also provides predetermined style options for layout that you can access using the style argument.
```{r}
map_nza + tm_style("bw")
map_nza + tm_style("classic")
map_nza + tm_style("cobalt")
map_nza + tm_style("col_blind")
```
Please reference section 8.2.5 of the online textbook for more information on what you can do to the layout.
## Faceted maps
Faceted maps are useful for representing how data change in relationship to another variable, such as time. Here is an example of population size of large cities changing over time (including predictions of the future).
Play around with the number of years included in this figure and the arguments for the tm_facets() function.
```{r}
urb_1970_2030 = urban_agglomerations %>%
filter(year %in% c(1970, 1990, 2010, 2030))
tm_shape(world) +
tm_polygons() +
tm_shape(urb_1970_2030) +
tm_symbols(col = "black", border.col = "white", size = "population_millions") +
tm_facets(by = "year", nrow = 2, free.coords = FALSE)
```
## Inset maps
An inset map is a smaller map rendered within or next to the main map and can be useful for adding more detail to your maps.
As an example, we can start by making a new spatial object
```{r}
nz_region = st_bbox(c(xmin = 1340000, xmax = 1450000,
ymin = 5130000, ymax = 5210000),
crs = st_crs(nz_height)) %>%
st_as_sfc()
```
Next, we can make the elevation map
```{r}
nz_height_map = tm_shape(nz_elev, bbox = nz_region) +
tm_raster(style = "cont", palette = "YlGn", legend.show = TRUE) +
tm_shape(nz_height) + tm_symbols(shape = 2, col = "red", size = 1) +
tm_scale_bar(position = c("left", "bottom"))
```
Now we can make the inset map
```{r}
nz_map = tm_shape(nz) + tm_polygons() +
tm_shape(nz_height) + tm_symbols(shape = 2, col = "red", size = 0.1) +
tm_shape(nz_region) + tm_borders(lwd = 3)
```
And put it all together
```{r}
library(grid)
nz_height_map
print(nz_map, vp = viewport(0.8, 0.27, width = 0.5, height = 0.5))
```
Another purpose of inset maps is to include create a single map of non-contiguous areas such as a map of the US.
First, we can get a map of the contiguous US
```{r}
us_states_map = tm_shape(us_states, projection = 2163) + tm_polygons() +
tm_layout(frame = FALSE)
```
Next, we can define maps for hawaii and alaska
```{r}
hawaii_map = tm_shape(hawaii) + tm_polygons() +
tm_layout(title = "Hawaii", frame = FALSE, bg.color = NA,
title.position = c("LEFT", "BOTTOM"))
alaska_map = tm_shape(alaska) + tm_polygons() +
tm_layout(title = "Alaska", frame = FALSE, bg.color = NA)
```
Finally, we can print these maps and define where we want them to go on the map
```{r}
us_states_map
print(hawaii_map, vp = grid::viewport(0.35, 0.1, width = 0.2, height = 0.1))
print(alaska_map, vp = grid::viewport(0.15, 0.15, width = 0.3, height = 0.3))
```
## Animated maps
Rather than using faceted plots, animated maps can help visualize the same data using less space and in a more intuitive way.
```{r}
urb_anim = tm_shape(world) + tm_polygons() +
tm_shape(urban_agglomerations) + tm_dots(size = "population_millions") +
tm_facets(along = "year", free.coords = FALSE)
```
This will create the animation and save it onto your computer. You'll want to designate the filepath so that you can easily find it. This will default into your current working directory. If you are using MacOS then you can view it as a gif by opening it using cmd+y
```{r}
#tmap_animation(urb_anim, filename = "urb_anim.gif", delay = 25)
```
## Interactive maps
The development of packages for interactive maps in R has made interactivity extremely accessible. 'tmap' makes this easy by allowing most static maps easily transferrable to interactive maps using tmap_mode()
See below for an example of turning 'map_nz' into a simple interactive map using tmap_mode("view")
```{r}
tmap_mode("view")
map_nz
```
Now that tmap_mode() has been set to "view", all of the maps generated with tmap will show up as interactive maps
```{r}
map_nza
```
You can return to static maps by using tmap_mode("plot")
```{r}
tmap_mode("plot")
map_nza
```
Another package that allows for quick generation of interactive maps is 'mapview'
```{r}
library(mapview)
trails %>%
st_transform(st_crs(franconia)) %>%
st_intersection(franconia[franconia$district == "Oberfranken", ]) %>%
st_collection_extract("LINE") %>%
mapview(color = "red", lwd = 3, layer.name = "trails") +
mapview(franconia, zcol = "district", burst = TRUE) +
breweries
```
leaflet is another option that is more low-level allowing for more customization
```{r}
pal = colorNumeric("RdYlBu", domain = cycle_hire$nbikes)
leaflet(data = cycle_hire) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircles(col = ~pal(nbikes), opacity = 0.9) %>%
addPolygons(data = lnd, fill = FALSE) %>%
addLegend(pal = pal, values = ~nbikes) %>%
setView(lng = -0.1, 51.5, zoom = 12) %>%
addMiniMap()
```
## More mapping options
To see more mapping options, you can check out the rest of the material in Chapter 8 of the online textbook. For example, this section goes into using leaflet and shiny to make interactive web apps.
## Exercises
These exercises rely on a new object, africa. Create it using the world and worldbank_df datasets from the spData package as follows:
```{r}
africa = world %>%
filter(continent == "Africa", !is.na(iso_a2)) %>%
left_join(worldbank_df, by = "iso_a2") %>%
dplyr::select(name, subregion, gdpPercap, HDI, pop_growth) %>%
st_transform("+proj=aea +lat_1=20 +lat_2=-23 +lat_0=0 +lon_0=25")
```
We will also use zion and nlcd datasets from spDataLarge:
```{r}
zion = read_sf((system.file("vector/zion.gpkg", package = "spDataLarge")))
nlcd = rast(system.file("raster/nlcd.tif", package = "spDataLarge"))
```
1. Create a map showing the geographic distribution of the Human Development Index (`HDI`) across Africa with base **graphics** (hint: use `plot()`) and **tmap** packages (hint: use `tm_shape(africa) + ...`).
- Name two advantages of each based on the experience.
- Name three other mapping packages and an advantage of each.
- Bonus: create three more maps of Africa using these three packages.
1. Extend the **tmap** created for the previous exercise so the legend has three bins: "High" (`HDI` above 0.7), "Medium" (`HDI` between 0.55 and 0.7) and "Low" (`HDI` below 0.55).
- Bonus: improve the map aesthetics, for example by changing the legend title, class labels and color palette.
1. Represent `africa`'s subregions on the map.
Change the default color palette and legend title.
Next, combine this map and the map created in the previous exercise into a single plot.
1. Create a land cover map of the Zion National Park.
- Change the default colors to match your perception of the land cover categories
- Add a scale bar and north arrow and change the position of both to improve the map's aesthetic appeal
- Bonus: Add an inset map of Zion National Park's location in the context of the Utah state. (Hint: an object representing Utah can be subset from the `us_states` dataset.)
1. Create facet maps of countries in Eastern Africa:
- With one facet showing HDI and the other representing population growth (hint: using variables `HDI` and `pop_growth`, respectively)
- With a 'small multiple' per country
1. Building on the previous facet map examples, create animated maps of East Africa:
- Showing first the spatial distribution of HDI scores then population growth
- Showing each country in order
1. Create an interactive map of Africa:
- With **tmap**
- With **mapview**
- With **leaflet**
- Bonus: For each approach, add a legend (if not automatically provided) and a scale bar