S’il te plaît, dessine-moi une carte (avec R)

En dataviz, savoir faire diagramme en barres et histogrammes, c’est une première étape. Mais quand il faut passer aux données spatiales, vous aurez besoin d’appeler la cartographie à la rescousse. Et si nous vous en parlons ici, c’est pour vous présenter son utilisation en R !

Avant de nous lancer corps et âme dans le code, il est essentiel de faire un petit rappel théorique sur la cartographie. (Promis, ça sera synthétique !)

Cartographies : rappels théoriques

C’est quoi une carte ? 

Cela peut vous paraître une question étrange, mais il est important de se la poser.

La projection d’une carte peut être divisée en deux éléments :

  • Une couche « fond », qui contient les contours des frontières, les sols, les reliefs, les éléments clés…
  • Une couche graphique, qui contient la représentation des variables à observer.

Pourquoi ce rappel ? Parce que le choix du fond est aussi important (voire parfois plus) que la couche graphique. En effet, ce dernier impose deux contraintes à votre travail — d’abord, il ne doit pas venir déranger la couche statistique, en ce sens que la lecture des informations projetées ne doit pas être court-circuitée par les informations du fond. Cependant, ce fond doit également être suffisamment fourni pour permettre une compréhension de la carte (nous y reviendrons plus tard avec quelques exemples).

Comment construire une carte ? 

Avant de vous lancer, posez vous un instant pour réfléchir à ce que vous souhaitez visualiser. En effet, sans préparation, vous risquez d’aboutir à ce que l’on appelle parfois une « carte à lire » — ces cartes avec tellement d’informations qu’un effort de lecture et de compréhension est nécessaire. À l’inverse, visez plutôt des résultats épurés, quitte à créer plusieurs cartes — six cartes à une seule variable facilement compréhensibles valent mieux qu’une carte illisible avec six variables. Car, au final, personne ne veut finir sur Junkcharts 🙂

Les différents éléments d’une carte

En dehors du fond, votre carte devra contenir deux grandes familles d’éléments. D’un côté, les éléments « data », autrement dit les différentes variables, flux et éléments visuels, et de l’autre, les titres, légendes, et échelles. 

Pour représenter vos données, vous pouvez faire appel à trois types d’éléments :

  • Les objets ponctuels (point, carré, etc),
  • Les objets linéaires (pour représenter les flux),
  • Les objets surfaciques, qui sont des aplats couvrant un espace de votre carte.

Chacun de ces objets peut être modifié en fonction de 6 variables visuelles : la taille, la couleur, le grain, l’orientation, la forme, et la couleur. Comment choisir ? Voici quelques règles incontournables :

  • Les valeurs continues absolues peuvent varier en taille
  • Les valeurs continues relatives varient en couleur
  • Les qualitatives varient en forme, en grain, ou encore en couleur

Bon, et si on passait à la mise en pratique ?

Créer une cartographie avec R

Bien choisir son fond

Première étape : choisir son fond. Pour cela, vous avez deux formats à votre disposition : vectoriel ou raster.

« Whaaaaaaaat? » entend-t-on au fond de la salle ? Pas de panique, voici un petit topo pour y voir clair. Le raster est un format de fond en jpg, bitmap, png, etc. — c’est-à-dire créé à partir de pixels. Notez que le raster supporte mal les changements d’échelle, et qu’il risque de pixeliser si vous zoomez. De son côté, le format vectoriel est composé de formes géométriques simples (polygones, arcs de cercle, etc), qui peuvent être déformées sans perdre leur qualité. En clair, dans la mesure du possible, ce dernier est LE format à préférer : il se « scale » mieux, vous permet de travailler en couche, et vous avez la possibilité d’attribuer des informations aux polygones.

Le système de projection

Bon, maintenant, comment représenter tout cela sur un graphique ? En utilisant un sytème de coordonnées géographiques. Vous connaissez déjà certainement ce fonctionnement : chaque point sur terre est repérable par un couple latitude-longitude — le premier exprimant un rapport nord-sud, le second un rapport nord-est. Par exemple, Paris est à une latitude de 48.862725 et une longitude de 2.287592 dans le système WGS-84 — le système de notation mondial, notamment utilisé par les GPS. 

Créer une carte avec ggmap

Enfin, un peu d’action ! Pour créer une carte « quick and dirty », nous allons utiliser le package `ggmap`, qui vous permet de télécharger des fonds raster depuis Google Map.

# Librairies 

library(tidyverse)
library(ggmap)

# Jeu de données 

dtst <- read_csv2("https://data.explore.star.fr/explore/dataset/vls-stations-topologie-td/download/?format=csv&timezone=Europe/Berlin&use_labels_for_header=true")
dtst <- dtst %>%
  separate(Coordonnées, into = c("lat","lon"), sep = ",") %>% 
  mutate(lat = as.numeric(lat),
         lon = as.numeric(lon)) 

Nous voici donc avec un tableau contenant les données sur les stations de vélo Star, à Rennes. Si vous jetez un oeil sur les colonnes `lat` et `long`, elles vous rappelleront tout simplement des emplacements x et y, à l’image d’une visualisation classique. C’est d’ailleurs ce que nous allons faire : représenter la variable longitude sur les x, et la variable latitude sur les y, avec en fond la ville de Rennes.

Au total, nous projetterons trois variables : une variable de position, une variable taille avec le nombre d’emplacements, et une variable qualitative, avec l’équipement en terminal CB ou non.

map <-qmap("rennes", zoom = 13)
map 

Ici, qmap télécharge un fond en effectuant la requête avec le niveau de zoom indiqué. Ce qui donne :

Cet élément map va être utilisé comme premier niveau de votre ggplot. Vous pouvez ensuite construire votre graphique en suivant la méthode classique.

map + 
  geom_point(data = dtst, aes(x = lon, y = lat, size = Emplacements, col = `Avec terminal CB`)) + 
  scale_size(range = c(0, 10)) + 
  labs(title = "Stations du vélo STAR à Rennes", 
       subtitle = "data.explore.star.fr", 
       caption = "ThinkR", 
       x = "", 
       y = "") + 
  theme(plot.title=element_text(margin=margin(20,20,20,20), size=18, hjust = 0.5))

 

Nous avons ici un exemple de mauvaise interaction entre le fond et le graph, les rectangles contenant les numéros des routes créant une possible gêne à la lecture. Alors, comment y remédier ? En changeant le fond.

map_bis <- ggmap::qmap("rennes", zoom = 13, maptype = "satellite")
map_bis + 
  geom_point(data = dtst, aes(x = lon, y = lat, size = Emplacements, col = `Avec terminal CB`)) + 
  scale_size(range = c(0, 10)) + 
  labs(title = "Stations du vélo STAR à Rennes", 
       subtitle = "data.explore.star.fr", 
       caption = "ThinkR", 
       x = "", 
       y = "") + 
  theme(plot.title=element_text(margin=margin(20,20,20,20), size=18, hjust = 0.5))

Un peu mieux, mais ce n’est toujours pas ça… alors, passons au vectoriel !

Créer une carte avec des données vectorielles

Ici, plus d’image satellite ou encore de plan : on récupère un tableau de données qui contient les contours des polygones qui, ensemble, dressent les contours de la ville (ou du département, de la région, du pays…). Ce format s’appelle shapefile, c’est celui qu’on retrouve par exemple sur le site d’Open Data de Rennes.

Une fois le shapefile téléchargé et dézippé dans votre espace de travail, vous retrouvez quatre fichiers, tous commençant par « perimetres-des-12-quartiers-de-la-ville-de-rennes », chacun avec une extension différente. N’y touchez pas, tout va être géré par R, la librairie rgdal et la fonction `fortify()` de ggplot2.

download.file(url = "https://data.rennesmetropole.fr/explore/dataset/perimetres-des-12-quartiers-de-la-ville-de-rennes/download/?format=shp&timezone=Europe/Berlin", 
 destfile = "rennes.zip")
unzip("rennes.zip")
library(rgdal)
map_vec <- readOGR(dsn=".", layer="perimetres-des-12-quartiers-de-la-ville-de-rennes") %>%
  fortify()

map_vec est un tableau qui contient votre carte en vectoriel, que vous pouvez projeter ainsi :

ggplot(map_vec, aes(long,lat, group=group)) + 
  geom_polygon(fill = "grey50") 

Bien, ajoutons maintenant nos variables !

ggplot(map_vec, aes(long,lat, group=group)) + 
  geom_polygon(fill = "grey50") + 
  # Fonction pour fixer les proportions de la carte
  coord_map() + 
  # Fonction qui n'est pas nécessaire, mais sert à renforcer la délimitation des frontières
  geom_path(data=map_vec, aes(long, lat, group=group), color="grey") +
  # Ajoutons les points 
  geom_point(data = dtst, aes(x = lon, y = lat, size = Emplacements, col = `Avec terminal CB`, group = NULL)) + 
  scale_size(range = c(0, 10)) +
  labs(title = "Stations du vélo STAR à Rennes", 
       subtitle = "data.explore.star.fr", 
       caption = "ThinkR", 
       x = "", 
       y = "") + 
  theme(plot.title=element_text(margin=margin(20,20,20,20), size=18, hjust = 0.5),
        axis.text.x=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank(),
        panel.background= element_blank())

 

Mieux ? Visuellement, oui, le résultat est meilleur. Ensuite, au niveau de la lecture, cela dépend de la question à laquelle vous cherchez à répondre ! Est-ce que vous visez des Rennais, qui connaitront le nom des quartiers ? Vous cherchez à montrer que peu de stations sont équipées d’un terminal CB, ou encore que la concentration est plus forte dans le centre ? Dans ce cas, cette carte fonctionne. À l’inverse, si vous souhaitez créer une carte pour les touristes, qui auront besoin du nom des rues, nous sommes face à un nouveau cas de fond qui dessert la lecture.

Encore une fois : tout dépend du message que vous souhaitez véhiculer 😉 Et si vous souhaitez en savoir plus, nous pouvons en reparler !


À propos de l'auteur

Colin Fay

Colin Fay

Data scientist & R Hacker


Commentaires


À lire également