---
date: "2021-01-01"
title: "10. Mapping With Style"
subtitle: "Turning up the style"
---
{width=75%}
> "*Werner Heisenberg is driving down the highway and a police officer stops him. “Sir, do you know you’re going 82 m.p.h.?” the officer asks. “Thanks a lot!” Heisenberg snaps. “Now I’m lost.”*"
>
> — Unknown
> "*Science flies you to the moon. Religion flies you into buildings.*"
>
> — Victor Stenger
```{r maps-opts, echo=FALSE}
#| eval: true
knitr::opts_chunk$set(
comment = "R>",
warning = FALSE,
message = FALSE
)
```
Now that you have learned the basics of creating a beautiful map in **`ggplot2`** it is time to look at some of the more particular things you will need to make your maps extra stylish. There are also a few more things you need to learn how to do before your maps can be truly publication quality.
If we have not yet loaded the **`tidyverse`** let us do so.
```{r maps-load}
#| eval: true
# Load libraries
library(tidyverse)
library(scales)
library(ggspatial)
# Load Africa map
load(here::here("data", "africa_map.RData"))
```
# Default maps
In order to access the default maps included with the **`tidyverse`** we will use the function `borders()`.
```{r maps-world, fig.cap="The built in global shape file."}
#| eval: true
ggplot() +
borders(col = "black", fill = "cornsilk", size = 0.2) + # The global shape file
coord_equal() # Equal sizing for lon/lat
```
Jikes! It is as simple as that to load a map of the whole planet. Usually you are not going to want to make a map of the entire planet, so let us see how to focus on just the area around South Africa.
```{r maps-SA-1, fig.cap="A better way to get the map of South Africa."}
#| eval: true
sa_1 <- ggplot() +
borders(size = 0.2, fill = "cornsilk", colour = "black") +
coord_equal(xlim = c(12, 36), ylim = c(-38, -22), expand = 0) # Force lon/lat extent
sa_1
```
That is a very tidy looking map of South(ern) Africa without needing to load any files.
# Specific labels
A map is almost always going to need some labels and other visual cues. You saw in the previous section how to add site labels. The following code chunk shows how this differs if yoou want to add just one label at a time. This can be useful if each label needs to be different from all other labels for whatever reason. You may also see that the text labels we are creating have `\n` in them. When R sees these two characters together like this it reads this as an instruction to return down a line. Let us run the code to make sure you see what this means.
```{r maps-labels, fig.cap="Map of southern Africa with specific labels."}
#| eval: true
sa_2 <- sa_1 +
annotate(
"text",
label = "Atlantic\nOcean",
x = 15.1,
y = -32.0,
size = 5.0,
angle = 30,
colour = "navy"
) +
annotate(
"text",
label = "Indian\nOcean",
x = 33.2,
y = -34.2,
size = 5.0,
angle = 330,
colour = "red4"
)
sa_2
```
# Scale bars
With your fancy labels added, let us insert a scale bar next. There is no default scale bar function in the **`tidyverse`**, which is why you have loaded the **`ggsn`** package. This package is devoted to adding scale bars and North arrows to **`ggplot2`** figures. There are heaps of options so you will just focus on one of them for now. It is a bit finicky so to get it looking exactly how you want it requires some guessing and checking. Please feel free to play around with the coordinates below. You may see the list of available North arrow shapes by running `northSymbols()`.
```{r maps-scale, fig.cap="Map of southern Africa with labels and a scale bar."}
#| eval: true
sa_3 <- sa_2 +
annotation_scale(
location = "bl", # bottom left; you can also specify "tl", "tr", etc.
width_hint = 0.2, # relative width of the scale bar
height = unit(0.3, "cm"), # scale bar height
text_cex = 0.8, # text size
pad_x = unit(0.5, "cm"), # horizontal offset
pad_y = unit(0.5, "cm"), # vertical offset
bar_cols = c("black", "white")
) +
annotation_north_arrow(
location = "bl",
which_north = "true", # true north, not grid north
pad_x = unit(3, "cm"), # adjust to approximate your original x.min/x.max
pad_y = unit(2, "cm"), # adjust to approximate your original y.min/y.max
style = north_arrow_fancy_orienteering
)
sa_3
```
<!-- # Insetting -->
<!-- In order to inset a smaller map inside of a larger map we must first create the smaller map. We have already loaded just such a map of Africa so we will use that for this example. -->
<!-- ```{r maps-mini, fig.align = "center"} -->
<!-- africa_map -->
<!-- ``` -->
<!-- And now to inset this map of Africa into our map of southern Africa we will need to learn how to create a 'grob'. This is very simple and does not require any extra work on our part. Remember that **`ggplot2`** objects are different from normal objects (i.e. dataframes), and that they have their own way of storing, accessing data. In order to convert any sort of thing into a format that ggplot understands we convert it into a grob and as shown below. Once converted, we may then plop it onto our figure/map wherever we please. Both of these steps are accomplished with the single function `annotation_custom()`. This is also a good way to add logos or any other sort of image to a map/figure. You can really go completely bananas. It is even possible to add GIFs. Such happy. Much excite. Very wonderment. -->
<!-- ```{r maps-inset, fig.cap="Map of southern Africa, with labels, scale bar, and an inset map of Africa."} -->
<!-- sa_4 <- sa_3 + -->
<!-- annotation_custom(grob = ggplotGrob(africa_map), -->
<!-- xmin = 20.9, xmax = 26.9, -->
<!-- ymin = -30, ymax = -24) -->
<!-- sa_4 -->
<!-- ``` -->
<!-- # Rounding it out -->
<!-- There are a lot of exciting things going on in our figure now. To round out our adventures in mapping let us tweak the lon/lat labels to a more prestigious convention. There are two ways to do this. One of which requires us to install the **`scales`** package. Do not worry, it is a small one! -->
<!-- ```{r maps-final, fig.cap="The final map with all of the bells and whistles."} -->
<!-- sa_final <- sa_4 + -->
<!-- scale_x_continuous(breaks = seq(16, 32, 4), -->
<!-- labels = c("16°E", "20°E", "24°E", "28°E", "32°E"), -->
<!-- position = "bottom") + -->
<!-- scale_y_continuous(breaks = seq(-36, -24, 4), -->
<!-- labels = c("36.0°S", "32.0°S", "28.0°S", "24.0°S"), -->
<!-- position = "right") + -->
<!-- labs(x = "", y = "") -->
<!-- sa_final -->
<!-- ``` -->
<!-- And lastly we save the fruits of our labours. -->
<!-- ```{r maps-final-save, eval=FALSE} -->
<!-- ggsave(plot = sa_final, filename = "figures/southern_africa_final.pdf", -->
<!-- height = 6, width = 8) -->
<!-- ``` -->