Aujourd'hui est le début d'une grande aventure puisque je me lance dans l'espace (enfin, les données spatiales, quoi), ce qui ne manquera pas de faire plaisir à mes petits collègues géographes. Je vais commencer par vous montrer les possibilités du package ggmap
qui comme son nom le laisse entendre est un peu le petit frère de ggplot2
(dont je vous ai déjà parlé ici, et qui fait l'objet d'un cours ici), et qui est dédié à la production de cartes tout en faisant usage des fonctionnalités de ggplot2
.
Premier pas: le fond de carte
Dans ce post je vais m'intéresser aux marchés alimentaires de la ville de Lyon (données récupérées sur le site de la ville)
Je vais donc récupérer un fond de carte pour Lyon, dont les latitudes-longitudes sont lat=45.759723, lon=4.842223 (merci Wikipedia).
Je charge ggmap
, je renseigne les coordonnées de Lyon, et je récupère un fond de carte correspondant à la ville de Lyon à l'aide de la fonction get_map
.
require(ggmap)
lyon=c(lat=45.759723, lon=4.842223)
lyon_map=get_map(location=lyon,zoom=13)
ggmap(lyon_map)
Edit: Comme plusieurs utilisateurs me l'ont fait remarquer, il faut désormais disposer d'une API key Google pour télécharger des fonds de carte avec ggmap...
Ici, j'ai "tâtonné" pour trouver le niveau de zoom ad hoc mais il y a d'autres manières de procéder (par exemple en utilisant la fonction calc_zoom
qui calcule le zoom adapté en fonction de l'étendue souhaitée).
La fonction get_map
a, outre les arguements location
et zoom
, deux arguments importants,
maptype
qui précise le type de carte souhaité ("terrain","satellite","roadmap","hybrid", etc.)source
qui précise la source des données ("google","osm" -pour Open Street Map-, etc.)
lyon_map_2=get_map(location=lyon,zoom=13,
maptype="satellite")
ggmap(lyon_map_2)
lyon_map_3=get_map(location=lyon,zoom=13,
maptype="watercolor", source="stamen")
ggmap(lyon_map_3)
Deuxième étape: spatialiser notre jeu de données
Considérons maintenant le jeu de données marches_lyonnais.csv:
data <- read.csv("../../lise.vaudor/Rdata/ggmap/marches_lyonnais.csv", header=TRUE, sep=";")
head(data)
## ID nom localisation arrt n_com jour heure
## 1 1 Ambroise Courtois Place Ambroise Courtois 8 40 mardi matin
## 2 1 Ambroise Courtois Place Ambroise Courtois 8 40 jeudi matin
## 3 1 Ambroise Courtois Place Ambroise Courtois 8 40 samedi matin
## 4 2 Ambroise Paré Boulevard Ambroise Pare 8 1 mercredi matin
## 5 2 Ambroise Paré Boulevard Ambroise Pare 8 1 dimanche matin
## 6 3 Bayard Cours Bayard 2 13 jeudi matin
Pour l'instant je n'ai pas de coordonnées spatiales pour mes données. Je vais donc tenter de récupérer des coordonnées (de type latitude-longitude) à partir des adresses. Pour cela on peut utiliser la fonction geocode
.
Je commence par utiliser les colonnes localisation et arrondissement de mon jeu de données pour recréer une adresse complète, et je me crée un petit jeu de données data_loc comportant les identifiants uniques des marchés et l'adresse correspondante:
adresse=paste0(data$localisation," 6900",data$arrt," Lyon")
data_loc=data.frame(ID=data$ID,
adresse=adresse)
data_loc=unique(data_loc)
head(data_loc)
## ID adresse
## 1 1 Place Ambroise Courtois 69008 Lyon
## 4 2 Boulevard Ambroise Pare 69008 Lyon
## 6 3 Cours Bayard 69002 Lyon
## 8 4 Rue Bellecombe 69006 Lyon
## 10 5 Place Belleville 69008 Lyon
## 12 6 Place Benedict Tessier 69005 Lyon
Je peux alors utiliser geocode
pour trouver les latitudes-longitudes correspondant aux adresses.
lonlat=geocode(as.vector(data_loc$adresse))
data_loc=data.frame(data_loc,lonlat)
head(data_loc)
## ID adresse lon lat
## 1 1 Place Ambroise Courtois 69008 Lyon 4.871257 45.74473
## 4 2 Boulevard Ambroise Pare 69008 Lyon 4.883713 45.73670
## 6 3 Cours Bayard 69002 Lyon 4.821048 45.74397
## 8 4 Rue Bellecombe 69006 Lyon 4.863359 45.76701
## 10 5 Place Belleville 69008 Lyon 4.853576 45.73445
## 12 6 Place Benedict Tessier 69005 Lyon 4.797599 45.75585
Je réunis alors le tout dans le jeu de données spatialisé data_sp en réalisant une jointure:
data_sp=merge(data,data_loc,by="ID")
Troisième étape: superposer nos données au fond de carte
C'est à partir de cette étape que l'on retrouve les outils de ggplot2
. On peut par exemple reprendre le deuxième fond de carte, et superposer un geom "point" de la manière suivante:
ggmap(lyon_map_3)+
geom_point(data=data_sp,
aes(x=lon,y=lat), col="red", size=2)
On peut ainsi exploiter les fonctionnalités les plus pratiques de ggplot2
, comme le fait de pouvoir relier une variable à une caractéristique graphique (ici par exemple on relie la taille du point au nombre de commerçants)
ggmap(lyon_map_3)+
geom_point(data=data_sp,
aes(x=lon,y=lat,size=n_com), col="red")
On peut aussi créer des "facettes" du même graphique selon des facteurs (ici le jour: je commence donc ici en indiquant l'ordre des jours qui sinon seraient simplement classés par ordre alphabétique)
levels(data_sp$jour)=c("lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche")
ggmap(lyon_map_3)+
geom_point(data=data_sp,
aes(x=lon,y=lat,size=n_com), col="red")+
facet_wrap(~jour)
Remarquez que ci-dessus, j'ai indiqué le jeu de données et les esthétiques de base (comme x et y) dans l'appel à la fonction geom_point
et non dans l'appel à la fonction ggmap
. Cela peut être plus pratique d'indiquer les informations de bases dans l'appel à ggmap
, en particulier si l'on superpose plusieurs geoms:
ggmap(lyon_map_3,
base_layer=ggplot(data=data_sp, aes(x=lon,y=lat))) +
geom_point(aes(size=n_com), col="red") +
geom_text(aes(label=nom), color="grey60",size=3)
6 Comments
Cyrille
Merci pour le partage d'informations.
Pourriez-vous me dire comment ajouter l'échelle de la carte?
lvaudor
Bonjour,
Malheureusement je n'ai pas de solution hyper simple à vous fournir, par contre vous pouvez vous inspirer de la solution proposée ici (dernière réponse, de "dww").
Alex
Bonjour ,
Super blog ! Cependant , j'ai essaye de reproduire votre carte mais le fichier marches_lyonnais.csv est vide :(.
Serait-il possible de remettre le bon fichier?
Merci d'avance.
lvaudor
Bonjour!
Effectivement, je ne sais pas ce qui est arrivé à ce fichier mais j'ai remis le bon !
Bon ggmap :-),
Lise
Jubar14
Coucou Lise, juste pour préciser aux nouveaux testeurs comme moi, que maintenant il faut visiblement une clé API Google pour pouvoir exécuter le code évoqué.
"Error: Google now requires an API key. See ?register_google for details"
Bonne journée 😉
lvaudor
Oui tout à fait!! Bien vu 🙂 Je vais faire un edit en tête de billet pour le préciser...