library(ggmap)
9 Mapas con ggmap
Con ggplot2
pueden construirse muchos tipos de gráficos de interés estadístico. Pero sus autores quisieron trasladar la arquitectura del paquete a otro ámbito: el de la representación de información georreferenciada. ggplot2
permite representar información geográfica (puntos, segmentos, etc.): basta con que las estéticas x
e y
se correspondan con la longitud y la latitud de los datos. Lo que permite hacer ggmap
es, en esencia, añadir a los gráficos ya conocidos una capa cartográfica adicional. Para eso usa recursos disponibles en la web a través de APIs (de Google y otros).
Parte de las funciones en ggmap
se apoyan en servicios que proporciona Google a través de APIs. Como se indica en ?register_google
, desde mediados de 2018 estos servicios no son de libre acceso sino que hay que registrarse en la plataforma de mapas de Google y obtener una key
personal. Además, es necesario abrir una cuenta, introducir la tarjeta de crédito, etc. Eso sí, Google proporciona cierto número de llamadas gratuitas al mes, mucho más que suficientes para un uso esporádico y no intensivo de estas herramientas, por lo que el coste de usarlas —al menos, en lo que concierne al presente capítulo— es cero.
A lo largo del capítulo se asumirá que el lector se ha registrado en la plataforma de Google siguiendo las instrucciones que se detallan ?register_google
. Como alternativa, puede explorar por su cuenta y riesgo otras plataformas o paquetes de R que proporcionan servicios similares, en ocasiones gratuitos, como caRtociudad
, pero que quedan fuera del alcance de este capítulo.
Un ejemplo sencillo ilustra los usos de ggmap
. En primer lugar, se carga (si se ha instalado previamente) el paquete:
Como se ha indicado en la nota anterior, es necesario registrar la key
de Google para poder usar gran parte de las funciones de dicho paquete:
register_google("saiiS_my_personal_key_W8sSA")
La función geocode
encapsula la consulta a dicha API y devuelve un objeto (un data.frame
) que contiene las coordenadas del lugar de interés:
<- geocode('Calle de Pedro Cerbuna 12, Zaragoza, España',
unizar source = "google")
La función get_map
consulta otro servicio de información cartográfica (GoogleMaps en el ejemplo siguiente) y descarga un mapa (que es, esencialmente, una imagen raster). La función exige una serie de argumentos: el nivel de zoom, si se quiere un mapa de carreteras o del terreno, etc. Son, de hecho, los parámetros que uno puede manipular con los controles de la interfaz habitual de GoogleMaps.
<- get_map(location = as.numeric(unizar),
map.unizar color = "color",
maptype = "roadmap",
scale = 2,
zoom = 16)
Es obvio que para poder invocar las dos funciones anteriores hace falta una conexión a internet. Sin embargo, el resto de las operaciones que se van a realizar se ejecutan localmente. Se puede, por ejemplo, representar el mapa directamente (haciendo ggmap(map.unizar)
). O bien se puede marcar sobre él el punto de interés:
ggmap(map.unizar) + geom_point(aes(x = lon, y = lat),
data = unizar, colour = 'red',
size = 4)
Como veremos a continuación, no estamos limitados a representar un único punto: unizar
podría ser una tabla con más de una fila y todos los puntos se representarían sobr el mapa.
Como puede apreciarse, la sintaxis es similar a la de ggplot2
. Una diferencia notables que, ahora, los datos se pasan en la capa, es decir, en este caso, en la función geom_point
.
9.1 Funciones de ggmap
ggmap
incluye muchas funciones que pueden clasificarse en tres categorías amplias:
- Funciones para obtener mapas (de diversos tipos y de distintos orígenes: Google, Stamen, OpenStreetMap)
- Funciones que utilizan APIs de Google y otros. Por ejemplo,
geocode
,revgeocode
yroute
consultan la información que tienen distintos proveedores de servicios vía API sobre las coordenadas de un determinado lugar; indican el lugar al que se refieren unas coordenadas y, finalmente, encuentran rutas entre dos puntos. Es conveniente recordar que las consultas a los servicios de Google Maps exige la aceptación de las condiciones de uso y que existe un límite diario en el número de consultas gratuitas. - Funciones que pintan mapas y que representan determinados elementos adicionales (puntos, segmentos, etc.) en mapas.
En esta sección se van a presentar los tres tipos de funciones de ggmap
.
9.1.1 Funciones para obtener mapas
ggmap
obtiene sus mapas, por defecto, de GoogleMaps. Sin embargo hay otros proveedores de mapas libres, como OpenStreetMap (OSM) o Stamen. Cada proveedor exige una serie de parámetros distintos y, por ejemplo, un zoom de 8 puede significar una escala distinta en GoogleMaps que en OSM. Sin embargo, los autores de ggmap
se han tomado la molestia de homogeneizar los argumentos de llamada para que sean aproximadamente equivalentes en todos los proveedores.
ggmap
incluye funciones específicas para cada proveedor, como get_googlemap
o get_stamenmap
, pero salvo para usos avanzados, es recomendable usar la función get_map
, que ofrece un punto de entrada único y homogéneo para el resto.
El gráfico siguiente muestra cuatro mapas obtenidos de diversos proveedores y con diversas opciones. En la fila superior, una capa de Google en modo imagen de satélite y otra estándar. En la inferior, dos mapas de Stamen, uno en modo toner y otro en modo watercolor o acuarela. Son solo cuatro de los muchos a los que la función get_map
puede acceder.
Ejercicio 9.1 Representa la ubicación de la universidad de Zaragoza (u otra que prefieras) con otros tipos de mapas, otros zums, etc.
9.1.2 Funciones para consultar APIs cartográficas
Muchos servicios de información cartográfica proporcionan APIs para realizar consultas. Las APIs se consultan, típicamente, con URLs convenientemente construidas. Por ejemplo, la URL
http://maps.googleapis.com/maps/api/geocode/json?address=Universidad+de+Zaragoza
consulta el servicio de geolocalización de GoogleMaps y devuelve las coordenadas de la Universidad de Zaragoza (así como otra información relevante en formato JSON). La función geolocate
de ggmap
facilita la consulta a dicho servicio: toma su argumento (el nombre de un lugar), construye internamente la URL, realiza la consulta (para lo que es necesario conexión a internet), lee la respuesta y le da un formato conveniente (en este caso, un data.frame
de R).
La de geolocalización no es la única API que permite consultar ggmap
. También permite invertir la geolocalización, es decir, dadas unas coordenadas, devolver el nombre del lugar al que se refieren:
revgeocode(as.numeric(unizar))
[1] "C. de Pedro Cerbuna, 12, 50009 Zaragoza, Spain"
Finalmente, route
permite obtener la ruta entre dos puntos distintos:
<- get_map("Madrid", source = "stamen", maptype = "toner", zoom = 12)
mapa <- route(from = "Puerta del Sol, Madrid", to = "Plaza de Castilla, Madrid")
ruta ggmap(mapa) +
geom_path(aes(x = start_lon, y = start_lat, xend = end_lon, yend = end_lat),
colour = "red", size = 2, data = ruta)
En el mapa anterior la ruta elegida por GoogleMaps para ir de la Puerta del Sol hasta la plaza de Castilla (dos plazas de Madrid) está marcado en rojo sobre un mapa de Stamen de tipo toner.
9.1.3 Funciones para representar elementos sobre mapas
Como se ha visto en las secciones anteriores, la función ggmap
permite representar un mapa descargado previamente. Además, a esa capa subyacente se le pueden añadir elementos (puntos, segmentos, densidades etc.) usando las funciones ya conocidas de ggplot2
: geom_point
, etc.
En ggplot2
existe una función, geom_path
que dibuja caminos (secuencias de segmentos). Se puede utilizar en ggmap
para dibujar rutas, aunque este paquete proporciona una función especial, geom_leg
que tiene la misma finalidad aunque con algunas diferencias menores: por ejemplo, los segmentos tienen las puntas redondeadas, para mejorar el resultado gráfico.
9.2 Ejemplos
En los ejemplos que siguen se va a utilizar el conjunto de datos crimes
que forma parte del paquete ggmap
y que incluye información geolocalizada de crímenes cometidos en la ciudad de Houston. En realidad, solo consideraremos los crímenes serios, es decir,
<- subset(crime, ! crime$offense %in% c("auto theft", "theft", "burglary")) crimes.houston
9.2.1 Puntos sobre mapas
El tipo de mapas más simples son los que se limitan a representar puntos sobre una capa cartográfica.
<- qmap("houston", zoom = 14, color = "bw")
HoustonMap +
HoustonMap geom_point(aes(x = lon, y = lat, colour = offense), data = crimes.houston, size = 1)
En el código anterior hemos usado la función qmap
, una función auxiliar que internamente llama primero get_map
y luego a ggmap
.
Los mecanismos conocidos de ggplot2
, como las facetas, están disponibles en ggmap
: es posible crear una retícula de mapas usando facet_wrap
. En este primer caso, descomponiendo el gráfico anterior por tipo de crimen.
+
HoustonMap geom_point(aes(x = lon, y = lat), data = crimes.houston, size = 1) +
facet_wrap(~ offense)
O, alternativamente, por día de la semana.
+
HoustonMap geom_point(aes(x = lon, y = lat), data = crimes.houston, size = 1) +
facet_wrap(~ day)
Ejercicio 9.2 Prueba a pintar las gasolineras en el mapa de España (fichero dat/carburantes_20050222.csv
).
Ejercicio 9.3 Baja datos georreferenciados del portal de datos abiertos del ayuntamiento de Madrid y represéntalos sobre un mapa.
9.2.2 Rutas sobre mapas
Vamos a hacer una digresión para representar información geográfica contenida en ficheros .kml
usando ggmap
como ejemplo de la versatilidad del paquete.
library(maptools)
# un fichero bajado el Ayto. de Madrid
<- getKMLcoordinates("data/130111_vias_ciclistas.kml") rutas
El conjunto de datos anterior contiene una lista de rutas (inspecciónalo), que queremos convertir en una única tabla para poder representarlas gráficamente con ggmap
.
library(plyr)
<- ldply(1:length(rutas), function(x) data.frame(rutas[[x]], id = x))
rutas <- get_map("Madrid", source = "stamen", maptype = "toner", zoom = 12)
mapa ggmap(mapa) + geom_path(aes(x = X1, y = X2, group = id), data = rutas, colour = "red")
9.2.3 Más allá de los puntos: densidades y retículas
Además de geom_point
, también están disponibles otros tipos de capas de ggplot2
, como stat_bin2d
, que cuenta el número de eventos que suceden en regiones cuadradas de un tamaño predefinido.
+
HoustonMap stat_bin2d(
aes(x = lon, y = lat, colour = offense, fill = offense),
size = .5, bins = 30, alpha = 1/2,
data = crimes.houston
)
O se puede usar stat_density2d
, que representa intensidades, para identificar las zonas de mayor criminalidad.
+
HoustonMap stat_density2d(aes(x = lon, y = lat, fill = ..level.., alpha = ..level..),
size = 2, data = crimes.houston,
geom = "polygon"
)
Ejercicio 9.4 Lee este artículo y consulta qué otras cosas (además de puntos) pueden representarse sobre un mapa.
9.3 Resumen y referencias
ggmap
extiende el paquete ggplot2
para representar información geográfica. Sin embargo, en R existen otros paquetes para procesar información geográfica. De hecho, existe una colección de paquetes construidos alrededor del fundamental, sf
(de Simple Features) que fue diseñado para aplicaciones en geoestadística y que permiten hacer de R, prácticamente, un GIS (geographic information system). Estos paquetes permiten, por ejemplo, procesar shapefiles, que son ficheros usados en muchos GIS para almacenar información geográfica. El INE y otros organismos estadísticos suelen diseminar información con una componente geográfica en este formato. sf
es el sucesor de sp
, aún popular peor en estado de progresiva desaparición, gracias al cual se han reorganizado los paquetes relacionados con la información geográfica alrededor de un nuevo estándar, Simple Feature Access (véase http://www.opengeospatial.org/standards/sfa).
Además de lo anterior, paquetes como leaflet
permiten crear mapas dinámicos en los que es posible hacer zum, desplegar marcadores, etc. De hecho, en múltiples aplicaciones y, en particular, las interactivas desarrolladas con shiny
o flexdashboard
, leaflet
es preferible a ggmap
.
Finalmente, los usuarios interesados en información geográfica española, tienen a su disposición el paquete caRtociudad
, que explota una API del Instituto Geográfico Nacional que proporciona servicios similares a los de ggmap
: mapas, geolocalización, rutas, etc. Tiene algunas ventajas con respecto a ggmap
, como que no tiene restricción en el número de llamadas y que, además, proporciona información administrativa adicional, como códigos postales, secciones censales o de referencias catastrales.
9.4 Ejercicios adicionales
Ejercicio 9.5 Busca rutas en tu localidad y represéntalas sobre un mapa.
Ejercicio 9.6 El fichero carburantes_20050222.csv
contiene información sobre todas las gasolineras de España y los precios de los carburantes. Incluye las coordenadas geográficas de los surtidores. Representa esos datos sobre un mapa de España (o de tu provincia o municipio). Modifica el tamaño (o color) de los puntos en función de, por ejemplo, el precio de los carburantes.