Resumen

El objetivo de este post es exponer una posible forma de realizar mapas en R visualizando un conjunto de observaciones cuando tenemos información de las coordenadas de los elementos a representar.


Creación de Mapas utilizando paquetes de R


Para generar mapas en R podemos importar archivos tipo shapefile (SHP) donde se almacena la ubicación geométrica y diversa información de atributos de entidades geográficas. En otro post expondré cómo trabajar con dichos archivos, cómo importar archivos shapefile y cómo trabajar con ellos. No obstante, existen también diversos paquetes que podemos utilizar para realizar mapas en R y sobre ellos trabajaremos en este post. Por ejemplo, utilizando los paquetes {mapdata} y {ggplot2} podemos generar un mapa del mundo estableciendo la siguiente orden:



library(mapdata)
library(ggplot2)
library(maps)
library(ggrepel)

# Guardamos la información en un nuevo dataframe llamado mapa_mundo

mapa_mundo <- map_data("world")


# Para visualizar el mapa utilizamos geom_polygon() 

library(tidyverse)

mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "black",
               color = "white")


Además, el mapa anterior podemos customizarlo a nuestro gusto utilizando las operaciones clásicas del paquete {ggplot2}.



mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey80",
               color = "white") +
  theme_minimal() +
  theme(
    axis.line = element_blank(),
    axis.text = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    panel.background = element_rect(colour= "black", size= 1)) +
  ggtitle( "Mapa Mundi") 


Asimismo, podemos generar mapas regionales indicando las coordenadas. Para realizar un mapa de España peninsular y Baleares, Portugal, sur de Francia y norte de África podemos indicar las siguientes coordenadas:



mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey80",
               color = "white") +
  theme_minimal() +
  theme(
    axis.line = element_blank(),
    axis.text = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    panel.background = element_rect(colour= "black", size= 1)) +
  ggtitle( "Mapa de la Península Ibérica") +
  coord_fixed (xlim= c(-12,5),
              ylim= c(35,45),
              ratio = 1.3)


De forma similar podemos representar en un mapa, por ejemplo, la región de América del Sur y zonas colindantes indicando las coordenadas adecuadas:



mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey80",
               color = "white") +
  theme_minimal() +
  theme(
    axis.line = element_blank(),
    axis.text = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    panel.background = element_rect(colour= "black", size= 1)) +
  ggtitle( "Mapa de América del Sur") +
  coord_fixed (xlim= c(-100,-25),
              ylim= c(-60,20),
              ratio = 1.2)


Podemos identificar el nombre de algunas ciudades de las siguiente forma:



ciudades <- c("Lima", "Sao Paulo", "Bogotá")
coordenadas <- data.frame( long = c(-77.0282364, -46.6388, -74.081749 ), 
                           lat= c(-12.0431805,-23.5489, 4.6097102),
                           stringsAsFactors = F) 
              
coordenadas$ciudades <- ciudades      



mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey80",
               color = "white") +
  theme_minimal() +
  theme(
    axis.line = element_blank(),
    axis.text = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    panel.background = element_rect(colour= "black", size= 1)) +
  ggtitle( "Mapa de América del Sur") +
  coord_fixed (xlim= c(-100,-25),
              ylim= c(-60,20),
              ratio = 1.2)+
  geom_point(data=coordenadas, aes(long, lat),
             color= "red", size=1) +
  geom_text_repel(data = coordenadas, 
                  aes(long, lat, label =ciudades))


Existe también un theme, usando la función theme_map() del paquete {ggthemes}, diseñado para representar mapas visualmente bastante agradables.



library(ggthemes)

ggplot() +
  borders("world", colour = "white", fill = "brown") +
  theme_map()


Visualización de mapas utilizando coordenadas geográficas


Para realizar este apartado vamos a utilizar el dataframe meteorites del proyecto Tidytuesday. Este dataset, que se ha construido con datos de The Meteoritical Society, incluye los meteoritos que han caído en la tierra y los que se han encontrado así como información de los mismos (nombre, id, tipo, class, masa, año encontrado, latitud, longitud y geolocalización).


En primer lugar descargamos el archivo .csv directamente del github de tidytuesday de la siguiente forma:



meteoritos <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-06-11/meteorites.csv")
## Parsed with column specification:
## cols(
##   name = col_character(),
##   id = col_double(),
##   name_type = col_character(),
##   class = col_character(),
##   mass = col_double(),
##   fall = col_character(),
##   year = col_double(),
##   lat = col_double(),
##   long = col_double(),
##   geolocation = col_character()
## )

# Quitamos los elementos que faltan (na´s) para la representación gráfica

meteoritos_mapa <- meteoritos %>%
  drop_na()

 

En primer lugar vamos a representar todos los meteoritos en el mapa del mundo, tanto los que se han detectado al caer (fell) como los encontrados (found). Para ello utilizaremos el theme theme_map() visto en el punto anterior y añadiremos un geom_point() con información de los meteoritos.



options(scipen = 999) # para evitar la anotación científica 

# Graficamos indicando 

mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey80",
               color = "white") +
  geom_point(data= meteoritos_mapa, 
             aes(x=long, y = lat, size = mass/1000), 
             stroke = F) +
  scale_size_continuous(name = "Kg") +
  ggtitle( "Meteoritos") +
  theme_map()

 

Existe como vemos una gran diferencia de tamaño entre los meteoritos incluidos en el dataframe. Veamos, por curiosidad, cuales son los meteoritos de más de 30mil kilos:



meteoritos %>%
  select(name, year, mass, fall) %>%
  filter( mass > 30000000) %>%
  arrange(desc(mass))
## # A tibble: 3 x 4
##   name             year     mass fall 
##   <chr>           <dbl>    <dbl> <chr>
## 1 Hoba             1920 60000000 Found
## 2 Cape York        1818 58200000 Found
## 3 Campo del Cielo  1575 50000000 Found


Hoba, Cape York y Campo del Cielo, meteoritos encontrados en Namibia, Groenlandia y Argentina respectivamente, son los meteoritos de mayor masa. Se puede ver una foto de ellos en el siguiente enlace.


Para diferenciar los meteoritos caídos (fell) y los encontrados (found) podemos asociar a cada uno de ellos un color de la siguiente forma:



mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey80",
               color = "white") +
  geom_point(data= meteoritos_mapa, 
             aes(x=long, y = lat, size = mass/1000, color = fall), 
             stroke = F) +
  scale_color_manual(values = c( "black", "orange"), name = " ") + 
  scale_size_continuous(name = "Kg") +
  ggtitle( "Meteoritos caídos y encontrados") +
  theme_map()


Para visualizar los meteoritos en una región determinada del globo debemos indicar las coordenadas tal y como se expuso previamente. Pongamos por ejemplo que nos interesa visualizar los meteoritos caídos (fell) en Europa, para ello podemos indicar los siguientes comandos:



# seleccionamos los meteoritos que nos interesa graficar

meteoritos_Europa <- meteoritos %>%
  filter(fall == "Fell") %>%
  drop_na() %>%
  filter(between(long, -12, 25),
         between(lat, 35, 65)) %>%
  arrange(mass)


# graficamos en un mapa de Europa (y escogemos un fondo oscuro)

mapa_mundo %>%
  ggplot() + 
  geom_polygon(aes(x=long, y=lat, group=group),
               fill= "grey30", color="white") +
  geom_point(data=meteoritos_Europa, aes(x=long, 
                                         y=lat, 
                                         size= mass/1000, 
                                         color= mass/1000), stroke=F) +
  coord_fixed(xlim= c(-12,25),
              ylim= c(35,65),
              ratio= 1.3)+
  ggtitle("Caída de meteoritos en Europa") +
  scale_size_continuous(name = "kg") +
  scale_color_gradient(low= "orange", high= "brown", name= "Kg") +
  guides(color= guide_legend()) +
  theme_classic() +
  theme(
    axis.line = element_blank(),
    axis.text = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    panel.background = element_rect(colour= "grey30", size= 1, fill= NA)
  ) 


Generación de mapas animados con {gganimate}


Utilizando el paquete {gganimate} es posible generar mapas animados partiendo de mapas como los creados en los apartados anteriores. Veamos por ejemplo algún ejemplo utilizando el mismo dataset de los meteoritos pero centrándonos en los caídos (fell) y, por lo tanto, obviando los meteoritos encontrados (found).



# Cargamos el paquete gganimate

library(gganimate)


# Creamos un nuevo dataset en el que no se tenga en cuenta los meteoritos encontrados (found) ni los que cayeron antes de 1800. 

meteoritos_Mundo <- meteoritos %>%
  filter(fall == "Fell") %>%
  filter(year > 1800) %>%
  drop_na() %>%
  arrange(mass)


# Generamos el mapa, que guardamos como mapa_animado y posteriormente generamos la animación con la función animate. 

mapa_animado <- mapa_mundo %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey20",
               color = "white") +
  geom_point(data= meteoritos_Mundo, 
             x = meteoritos_Mundo$long, 
             y = meteoritos_Mundo$lat, 
             color = "orange",
             alpha = 0.7,
             size = 0.2) +
  transition_states(meteoritos_Mundo$year,
                    transition_length = 1, 
                    state_length = 1) +
  shadow_mark(past = TRUE) +
  labs( title = "Caída de meteoritos desde 1800 hasta 2013 \n Year :{closest_state}",
        caption = "The Meteoritical Society | @Ruben46563154") +
  theme_map() +
  theme(plot.title = element_text(size = 18, hjust = 0.5))
  

animate(mapa_animado, nframes= 450, fps = 10)