Vector maps

Packages

library(tidyverse, quietly = TRUE)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggmap)
## ℹ Google's Terms of Service: <https://mapsplatform.google.com>
##   Stadia Maps' Terms of Service: <https://stadiamaps.com/terms-of-service/>
##   OpenStreetMap's Tile Usage Policy: <https://operations.osmfoundation.org/policies/tiles/>
## ℹ Please cite ggmap if you use it! Use `citation("ggmap")` for details.
# library(rnaturalearth)
# library(rnaturalearthdata) # devtools::install_github("ropensci/rnaturalearthdata")
# library(rnaturalearthhires) # devtools::install_github("ropensci/rnaturalearthhires")

Lots of other packages in examples (notes and wider internet): sf (simple features), terra, and many more.

Functions

Data for map

m1 <- map_data("world")
m1lake <- map_data("lakes")
# m1 |> filter(region == "Canada")
# france, italy, lakes, nz, county (USA), state (USA), usa (coastline), world, world2 (centered on Pacific Ocean)
# canada.cities, world.cities
# see: help(package = "maps") for details

There are many “regions” and “subregions” within some of these maps:

count(m1, region) |> head()
##           region   n
## 1    Afghanistan 410
## 2        Albania 113
## 3        Algeria 383
## 4 American Samoa   8
## 5        Andorra  19
## 6         Angola 338
m1 |> filter(region == "Canada") |> count(subregion)
##                             subregion    n
## 1                                  10    6
## 2                                 100   37
## 3                                 103   21
## 4                                 106   11
## 5                                  11   12
## 6                                 110   19
## 7                                 122   10
## 8                                 123   14
## 9                                 126   24
## 10                                127   17
## 11                                128   22
## 12                                131   29
## 13                                140   22
## 14                                146   12
## 15                                 15    8
## 16                                 22    7
## 17                                 27  412
## 18                                 40    8
## 19                                 42    9
## 20                                 43   14
## 21                                 45   12
## 22                                 46   18
## 23                                 49   13
## 24                                  5    6
## 25                                 50    9
## 26                                 54   12
## 27                                 55    8
## 28                                 56   12
## 29                                 58   15
## 30                                 60   14
## 31                                 61    9
## 32                                 62   12
## 33                                 63   14
## 34                                 64   14
## 35                                 65   10
## 36                                 66    9
## 37                                 67   12
## 38                                 71    8
## 39                                 85    9
## 40                                 86   12
## 41                                 87   17
## 42                                  9    9
## 43                                 90    7
## 44                                 93    9
## 45                                 99   14
## 46                   Air Force Island   21
## 47                     Akpatok Island   16
## 48               Amund Ringnes Island   67
## 49                   Anticosti Island   27
## 50                 Aristazabal Island   13
## 51                Axel Heiberg Island  307
## 52                                 BC   15
## 53                      Baffin Island 1440
## 54                       Banks Island  145
## 55                    Bathurst Island  169
## 56                     Belcher Island   59
## 57                        Bell Island   11
## 58                         Big Island   20
## 59                      Borden Island   45
## 60                        Bray Island   22
## 61                       Brock Island   24
## 62                 Byam Martin Island   25
## 63                       Bylot Island   56
## 64                     Calvert Island   15
## 65                     Cameron Island   27
## 66                 Cape Breton Island   80
## 67               Chapman Lewes Island   11
## 68                     Charles Island   13
## 69                    Charlton Island   12
## 70                       Coats Island   35
## 71                      Coburg Island   16
## 72                    Cornwall Island   25
## 73                  Cornwallis Island   53
## 74                       Devon Island  331
## 75                      Edgell Island   19
## 76                    Eglinton Island   23
## 77               Ellef Ringnes Island  126
## 78                   Ellesmere Island  771
## 79                       Emerald Isle   13
## 80                      Flores Island    8
## 81                        Fogo Island   12
## 82                       Foley Island   21
## 83                     Galiano Island    8
## 84                   Gateshead Island   15
## 85                      Graham Island   58
## 86                 Grand Manan Island    7
## 87                    Harrison Island   14
## 88                      Helena Island   13
## 89                    Herschel Island    9
## 90                        Ile Lameque   10
## 91               Ile du Cap aux Meule   20
## 92                  Jenny Lind Island   16
## 93                   Jens Munk Island   38
## 94              King Christian Island   20
## 95                King William Island  104
## 96                        Koch Island   20
## 97                   Loks Land Island   17
## 98                    Lougheed Island   27
## 99              Mackenzie King Island   52
## 100                     Mansel Island   33
## 101                      Matty Island   32
## 102                    Meighen Island   27
## 103                  Melbourne Island   16
## 104                   Melville Island  297
## 105                  Merasheen Island   12
## 106                       Mill Island   11
## 107                    Moresby Island   51
## 108                  New World Island   16
## 109                      Newfoundland  455
## 110                     Nootka Island   17
## 111                 North Kent Island   26
## 112                 Nottingham Island   20
## 113                    Porcher Island   25
## 114                   Prescott Island   18
## 115             Prince Charles Island   39
## 116              Prince Edward Island   77
## 117             Prince Patrick Island  160
## 118            Prince of Wales Island  220
## 119             Princess Royal Island   29
## 120                     Quadra Island   14
## 121                    Redonda Island   11
## 122                 Resolution Island   20
## 123 Royal Geographical Society Island   39
## 124                    Russell Island   27
## 125                      Sable Island    9
## 126                  Salisbury Island    9
## 127                 Saltspring Island   11
## 128                      Smith Island    9
## 129                   Somerset Island   90
## 130                Southampton Island  134
## 131                 Stefansson Island   33
## 132                     Texada Island   13
## 133                    Tukarak Island   16
## 134                  Vancouver Island  166
## 135                 Vansittart Island   44
## 136                   Victoria Island  427
## 137                      Wales Island   28
## 138                      White Island   24
## 139                     Winter Island   12
## 140                              <NA> 3317

Political borders and territorial disputes: maps will undoubtedly be incomplete, inaccurate, or conflict with some people’s political views whether in Canada (Québec, Labrador), France (St Pierre & Miquelon), China, Palestine, Russia, etc.

Make a map

ggplot(m1, aes(map_id = region)) +
    geom_map(fill = "darkred", color = NA, 
             linewidth = 0.1, map = m1, alpha = 0.5) +
  expand_limits(x = c(-180,180), y = c(-85, 85) )

Combine the land and lake maps.

ggplot(m1, aes(map_id = region)) +
  geom_map(data = m1, fill = "white", color = "black", 
           linewidth = 0.2, alpha = 1, map = m1) +
  geom_map(data = m1lake, map = m1lake,
           fill = "blue", color = NA) +
  expand_limits(x = c(-180,180), y = c(-85, 85) )

Show just one region

m2 <- m1 |> filter(region == "Canada") 
m2 |> summarize(min_lat = min(lat), max_lat = max(lat), 
                min_long = min(long), max_long = max(long))
##    min_lat  max_lat  min_long  max_long
## 1 41.67485 83.11611 -141.0022 -52.65366
ggplot(m2, aes(map_id = region)) +
  geom_map(fill = "white", color = "black", linewidth = 0.5, map = m2)  +
  coord_map("albers", 60, 90) +
  # coord_map("lambert", 42, 50) +
  theme(axis.title = element_blank(), axis.text = element_blank(),
        axis.ticks = element_blank()) +
  expand_limits(x = c(-141, -50), y = c(41, 85))

ggplot(m2, aes(map_id = region)) +
  geom_map(fill = "white", color = "black", linewidth = 0.5, map = m2)  +
  coord_map("lambert", 42, 50) +
  theme(axis.title = element_blank(), axis.text = element_blank(),
        axis.ticks = element_blank()) +
  expand_limits(x = c(-141, -50), y = c(41, 85))

Note, this course is not making political statements when drawing maps.

m2 <- m1 |> filter(region == "Ukraine") 
m2 <- m1 |> filter(region == "Iran")
m2 <- m1 |> filter(region == "Chile")
m2 <- m1 |> filter(region == "Israel")
m2 <- m1 |> filter(region == "Palestine")
m2 <- m1 |> filter(region == "China")
m2 <- m1 |> filter(region == "Taiwan")
m2 <- m1 |> filter(region == "USA")
m2 <- m1 |> filter(region == "USA", subregion == "Hawaii")
m2 <- map_data("usa")
m2 <- m1 |> filter(region == "France")
m2 <- map_data("france") # more detail
ggplot(m2, aes(map_id = region, x = long, y = lat)) +
  geom_map(fill = "white", color = "black", size = 0.5, map = m2) +
  coord_map("mollweide") +
  expand_limits(x = range(m2$long), y = range(m2$lat))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Sometimes it is useful to have a world map centred on the Pacific Ocean.

m2 <- map_data("world2")
ggplot(m2, aes(map_id = region)) +
  geom_map(fill = "white", color = "black", size = 0.5, map = m2) +
  # coord_map("gilbert") 
  expand_limits(x = c(0, 360), y = c(-90, 90)) +
  coord_map("mollweide") 

  # coord_map("lambert", -25, 25) # not good for the whole globe
  # coord_map("albers", -25, 25)
m2 <- map_data("world")
ggplot(m2, aes(map_id = region)) +
  geom_map(fill = "white", color = "black", size = 0.5, map = m2) +
  # coord_map("gilbert") 
  expand_limits(x = c(-180, 180), y = c(-90, 90)) +
  coord_map("mollweide") 

  # coord_map("lambert", -25, 25) # not good for the whole globe
  # coord_map("albers", -25, 25)

Get a list of projections from help(“mapproject”) (in mapproj package).

Colouring regions

You can use a second data frame to add fill colours to a region. This second table must name the regions with the same codes as the map.

values <- tibble( region = m1 |> pull(region) |> unique())
values <- values |> mutate(value = runif(nrow(values)))
map2 <- ggplot(values, aes(map_id = region)) + 
        geom_map(aes(fill = value),
                 map = m1,
                 colour = "white", 
                 alpha = 1, linewidth = 0.2) +
   expand_limits(x = c(-180,180), y = c(-80,80)) +
   theme_bw() +
  coord_map("mollweide")
map2

map2 + theme_void() # removes axes, labels; leaves legend

Show just a few regions

map2 <- ggplot(m1, aes(map_id = region)) + 
  geom_map(fill = "gray", color = "white", map = m1, linewidth = 0.2) + 
  geom_map(aes(fill = value),
           data = values |> slice_sample(n = 50),
           map = m1,
           colour = "white", alpha = 1, size=0.2) +
   expand_limits(x = c(-180,180), y = c(-80,80)) +
   theme_bw() +
  coord_map("mollweide")
map2 + theme_void()

Adding points

Start with some data:

library(maps)
## 
## Attaching package: 'maps'
## The following object is masked from 'package:purrr':
## 
##     map
canada.cities |> head()
##            name country.etc    pop   lat    long capital
## 1 Abbotsford BC          BC 157795 49.06 -122.30       0
## 2      Acton ON          ON   8308 43.63  -80.03       0
## 3 Acton Vale QC          QC   5153 45.63  -72.57       0
## 4    Airdrie AB          AB  25863 51.30 -114.02       0
## 5    Aklavik NT          NT    643 68.22 -135.00       0
## 6    Albanel QC          QC   1090 48.87  -72.42       0

Add points to a map:

library(ggrepel)
m2 <- m1 |> filter(region == "Canada") 
ggplot(m2) +
  geom_map(aes(map_id = region),
           fill = "white", color = "black", linewidth = 0.5, map = m2) +
  geom_point(data = canada.cities,
             aes(x = long, y = lat),
             colour = "lightblue", size = 0.25) +
  geom_label_repel(data = canada.cities |> filter(pop > 500000),
             aes(x = long, y = lat, label = name),
             size = 3) +
  geom_point(data = canada.cities |> filter(pop > 500000),
             aes(x = long, y = lat),
             size = 0.75, color = "red") +
  coord_map("albers", 60, 90) + 
  theme_void()