Ce document contient quelques explorations cartographiques de la base de données World Urbanization Prospects des Nations Unies.

repo : https://github.com/rCarto/Intro_a_la_carto_avec_R/blob/master/ex/ville.Rmd

1 Téléchargement et préparation des données

1.1 Téléchargement

Il est possible de télécharger n’importe quel fichier directement à partir de R. Nous allons d’abord télécharger un fond de carte des pays du monde, puis les bases de données concernant les agglomérations urbaines de plus de 300000 habitants en 2014.

# World basemap
download.file(url = "https://raw.githubusercontent.com/riatelab/basemaps/master/World/countries.geojson",
              destfile = "data/country.geojson")
# Graticules layer
download.file(url = "https://raw.githubusercontent.com/riatelab/basemaps/master/World/graticule30.geojson",
              destfile = "data/graticule.geojson")
# Population data base
download.file(url = "https://esa.un.org/unpd/wup/CD-ROM/WUP2014_XLS_CD_FILES/WUP2014-F12-Cities_Over_300K.xls",
              destfile = "data/citypop.xls")
# Growth rate data base
download.file(url = "https://esa.un.org/unpd/wup/CD-ROM/WUP2014_XLS_CD_FILES/WUP2014-F14-Growth_Rate_Cities.xls",
              destfile = "data/cityevo.xls")

1.2 Préparation

Une fois les données téléchargées, il va être nécessaire de les préparer pour l’analyse. Nous allons d’abord les importer.

# libraries
library(sf)
library(readxl)

# import
country <- st_read(dsn = "../data/country.geojson", quiet = TRUE)
graticule <- st_read(dsn = "../data/graticule.geojson", quiet = TRUE)
citypop <- data.frame(read_excel("../data/citypop.xls", skip = 16))
cityevo <- data.frame(read_excel("../data/cityevo.xls", skip = 16))

Les données sur les villes sont distribuer dans deux tables différentes que nous allons joindre.

# jointure entre les 2 tableaux de données
city <- merge(x = citypop, y = cityevo[, c(4,9:24)], by = "City.Code")

Nous allons ensuite transformer la table city (un objet data.frame) en couche d’information géographique (un objet sf).

# construction de la couche city
city <- st_as_sf(city, 
                 coords = c("Longitude","Latitude"), 
                 crs = 4326) # On indique le systeme de coordonnées utilisé, ici WGS84

Nous pouvons aussi choisir d’utiliser une projection cartographique particulière, ici la projection de Robinson

# transformation de la projection WGS84 => Robinson
country <- st_transform(x = country, crs = 54030)
graticule <- st_transform(x = graticule, crs = 54030)
city <- st_transform(x = city, crs = 54030)

Nous pouvons maintenant vérifier que toutes les couches d’informations sont bien présente en réalisant une première carte très simple.

# Cartes
plot(st_geometry(graticule))
plot(st_geometry(country), add = TRUE)
plot(st_geometry(city), add = TRUE)
title(main ="Agglomérations urbaines de plus de 300 000 habitants en 2014", 
      sub = "Source : WUP 2014")

2 Cartographie

2.1 Position des villes

Il est possible d’améliorer cette première carte en paramétrant finement les élément affichés.

# paramétrage des marges de la figure
par(mar = c(0,0,1.2,0))
# affichage des différentes couches
plot(st_geometry(graticule), col = "lightblue", border = "white", lwd = 0.2)
plot(st_geometry(country), col = "ivory4", border ="ivory3", lwd = 0.5, add=TRUE)
plot(st_geometry(city), pch = 21, cex = 0.5, lwd = 1, col = "white", bg = "red", add = TRUE)
# ajout du titre et de la source
mtext(text = "Agglomérations urbaines de plus de 300 000 habitants en 2014", side = 3)
mtext(text = "Source : WUP 2014", side = 1, line = -1, adj = 0.99, cex = 0.75)

2.2 Population des villes en 2015

La fonction propSymbolsLayer du package cartography permet d’afficher des cercles proportionnels. La fonction layoutLayer permet d’afficher un titre et une source facilement.

library(cartography)
# acceder à l'aide de la fonction :
# ?propSymbolsLayer
par(mar = c(0,0,1.2,0))
plot(st_geometry(graticule), col = "lightblue", border = "white", lwd = 0.2)
plot(st_geometry(country), col = "ivory4", border ="ivory3", lwd = 0.5, add=TRUE)
# affichage des cercles proportionnels
propSymbolsLayer(x = city, var = "X2015")
# affichage du titre et des sources
layoutLayer(title = "Population des agglomérations urbaines en 2015", 
            sources = "WUP, 2014", author = "T. Giraud, 2017", 
            scale = NULL)

Cette carte peut être paramétrée plus finement (position de la légende, taille et couleur des cercles…)

par(mar = c(0,0,1.2,0))
plot(st_geometry(graticule), col = "lightblue", border = "white", lwd = 0.2)
plot(st_geometry(country), col = "ivory4", border ="ivory3", lwd = 0.5, add=TRUE)
propSymbolsLayer(x = city, var = "X2015", col = "#921010", border = "white", 
                 lwd = 0.5, symbols = "circle", inches = 0.2, 
                 legend.pos = "topleft", legend.title.cex = 0.7,
                 legend.title.txt = "Population en 2015\n(en milliers)")
layoutLayer(title = "Population des agglomérations urbaines en 2015", 
            sources = "WUP, 2014", author = "T. Giraud, 2017", 
            scale = NULL, tabtitle = TRUE, frame = FALSE)

Il est possible d’aller encore plus loin dans le parématrage de la légende avec la fonction legendCirclesSymbols.

par(mar = c(0,0,1.2,0))
plot(st_geometry(graticule), col = "lightblue", border = "white", lwd = 0.2, bg = "cornsilk2")
plot(st_geometry(country) + c(100000,-100000), add=T, col = "grey30", border = NA)
plot(st_geometry(country), col = "ivory4", border ="ivory3", lwd = 0.5, add=TRUE)
propSymbolsLayer(x = city, var = "X2015", col = "#721010", border = "white", 
                 lwd = 0.5, symbols = "circle", inches = 0.2, 
                 legend.pos = "n")
legendCirclesSymbols(pos = c(-13317499, -6284211 ),
                     title.txt = "Population en 2015\n(en milliers)", 
                     title.cex = 0.6, cex = 0.75, col = "#921010",
                     var = c(300, 5000, 20000, 38000),
                     inches = 0.2, style = "e")
layoutLayer(title = "Population des agglomérations urbaines en 2015", 
            sources = "WUP, 2014", author = "T. Giraud, 2017", col = "black", 
            coltitle = "white", scale = NULL, frame = FALSE, tabtitle = TRUE)

2.3 Évolution de la population des villes

La fonction propSymbolsChoroLayer permet d’afficher des symbols proportionnels colorés en fonction de la discrétisation d’une autre variable.

par(mar = c(0,0,1.2,0), bg = "white")
plot(st_geometry(graticule), col = "lightblue", border = "white", lwd = 0.2, bg = "cornsilk2")
# ajout d'un ombrage pour les pays du monde
plot(st_geometry(country) + c(100000,-100000), add=T, col = "grey30", border = NA)
plot(st_geometry(country), col = "ivory4", border ="ivory3", lwd = 0.5, add=TRUE)
# choix des bornes de la discrétisation du taux de croissance
bks <- c(min(city$X2010.2015), 0, 1, 2, 3, 4, max(city$X2010.2015))
# choix des couleurs
cols <- carto.pal("wine.pal", 1, "green.pal", 5)
propSymbolsChoroLayer(x = city, var = "X2015", border = "white",legend.title.cex = 0.6,
                 lwd = 0.5, symbols = "circle", inches = 0.2,
                 var2 = "X2010.2015", breaks = bks, col = cols,
                 legend.var.title.txt = "Population en 2015\n(en milliers)",
                 legend.var2.title.txt = "Taux de croissance\nannuel moyen\n(2000-2015)",
                 legend.var.pos = "topright", 
                 legend.var2.pos = "topleft", legend.values.cex = 0.6)
layoutLayer(title = "Population des agglomérations urbaines en 2015", 
            sources = "WUP, 2014", author = "T. Giraud, 2017", col = "black", 
            coltitle = "white", scale = NULL, frame = FALSE,  tabtitle = TRUE)

Il est aussi possible de produire une carte sur une zone particulière du monde, ici la Chine.

par(mar = c(0,0,1.2,0), bg = "white")
lest <- st_bbox(country[country$ISO3 %in% c('CHN'),])
plot(st_geometry(graticule), col = "lightblue", border = "white", lwd = 0.2, 
     bg = "cornsilk2", xlim = lest[c(1,3)], ylim = lest[c(2,4)])
plot(st_geometry(country) + c(20000,-20000), add=T, col = "grey30", border = NA)
plot(st_geometry(country), col = "ivory4", border ="ivory3", lwd = 0.5, add=TRUE)
propSymbolsChoroLayer(x = city, var = "X2015", border = "white",legend.title.cex = 0.6,
                      lwd = 0.5, symbols = "circle", inches = 0.2,
                      var2 = "X2010.2015", breaks = bks, col = cols,
                      legend.var.title.txt = "Population en 2015\n(en milliers)",
                      legend.var2.title.txt = "Taux de croissance\nannuel moyen\n(2000-2015)",
                      legend.var.pos = "topright", legend.var.frame = T,legend.var2.frame = TRUE,
                      legend.var2.pos = "topleft", legend.values.cex = 0.6)
layoutLayer(title = "Population des agglomérations urbaines en 2015", 
            sources = "WUP, 2014", author = "T. Giraud, 2017", col = "black", 
            coltitle = "white", scale = NULL, frame = FALSE, tabtitle = TRUE)

3 Cartographie animée

Le package animation permet de réaliser des graphique animés. Nous créons ici un carte animée de la population des villes.

library(animation)

png(filename = "../img/map-%02d.png", width = 1200, height = 637, res = 120)
for (i in 7:23){
  par(mar = c(0,0,1.2,0), bg = "white")
  plot(st_geometry(graticule), col = "lightblue", border = "white", lwd = 0.2, bg = "cornsilk2")
  plot(st_geometry(country) + c(100000,-100000), add=T, col = "grey30", border = NA)
  plot(st_geometry(country), col = "ivory4", border ="ivory3", lwd = 0.5, add=TRUE)
  propSymbolsLayer(x = city, var = names(city)[i], col = "#921010", 
                   legend.pos = "n",fixmax = 38000,
                   border = "white", lwd = 0.5, symbols = "circle", 
                   inches = 0.2)
  legendCirclesSymbols(pos = c(-13317499, -6284211 ),
                       title.txt = "Population\n(en milliers)", 
                       title.cex = 0.6, cex = 0.75, col = "#921010",
                       var = c(300, 5000, 20000, 38000),
                       inches = 0.2, style = "e")
  layoutLayer(title = "Population des agglomérations urbaines de 1950 à 2030", 
              sources = "WUP, 2014", author = "T. Giraud, 2017", col = "black", 
              coltitle = "white", scale = NULL, frame = FALSE, tabtitle = TRUE)
  text(x = -15874390, y = 8168850, labels = substr(names(city)[i], 2,5), cex = 1.5, font = 2)
}
dev.off()

ani.options(interval = 1)
setwd("../img")
im.convert("map*.png", output = "animation.gif")
setwd("../ex")

4 Pour la reproductibilité…

Voici les informations sur ma configuration :

sessionInfo()
## R version 3.4.2 (2017-09-28)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.3 LTS
## 
## Matrix products: default
## BLAS: /usr/lib/libblas/libblas.so.3.6.0
## LAPACK: /usr/lib/lapack/liblapack.so.3.6.0
## 
## locale:
##  [1] LC_CTYPE=fr_FR.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=fr_FR.UTF-8        LC_COLLATE=fr_FR.UTF-8    
##  [5] LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=fr_FR.UTF-8   
##  [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] animation_2.5     cartography_2.0.2 sp_1.2-5          readxl_1.0.0     
## [5] sf_0.5-5         
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_0.12.14     knitr_1.17       magrittr_1.5     units_0.4-6     
##  [5] lattice_0.20-35  rlang_0.1.4      stringr_1.2.0    udunits2_0.13   
##  [9] tools_3.4.2      grid_3.4.2       e1071_1.6-8      DBI_0.7         
## [13] rgeos_0.3-26     htmltools_0.3.6  class_7.3-14     yaml_2.1.14     
## [17] rprojroot_1.2    digest_0.6.12    tibble_1.3.4     evaluate_0.10.1 
## [21] rmarkdown_1.8    stringi_1.1.6    compiler_3.4.2   cellranger_1.1.0
## [25] backports_1.1.1  classInt_0.1-24