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 locationet 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)