6 Visualización dinámica

Instalación/carga librerías/datos utilizados

if (!require(highcharter)) install.packages('highcharter') 
library(highcharter) 
if (!require(fpp3)) install.packages('fpp3') 
library(fpp3)
if (!require(RColorBrewer)) install.packages('RColorBrewer') 
library(RColorBrewer)
if (!require(openxlsx)) install.packages('openxlsx') 
library(openxlsx) 
if (!require(leaflet)) install.packages('leaflet') 
library(leaflet)  
if (!require(geojsonio)) install.packages('geojsonio') 
library(geojsonio) 
if (!require(plotly)) install.packages('plotly') 
library(plotly)
if (!require(ggplot2)) install.packages('ggplot2') 
library(ggplot2)
if (!require(tidyverse)) install.packages('tidyverse') 
library(tidyverse)
owid_country <- read.xlsx("https://ctim.es/AEDV/data/owid_country.xlsx",sheet=1) %>%
  as_tibble()

La visualización dinámica, donde el usuario puede interactuar con los gráficos, pasando el ratón por encima del gráfico, tiene un gran interés para presentar los datos, especialmente cuando los datos se presentan en páginas web como ficheros html. Utilizaremos diversas librerías como plotly que permite crear un gráfico interactivo de algunos objetos creados con ggplot, esto nos facilita mucho la tarea porque el código es idéntico al que genera el gráfico con ggplot, lo único que cambia es la llamada a la hora de dibujar el gráfico que se hace con la función ggplotly. Para la visualización interactiva de series temporales usaremos la librería highcharter que permite gestionar directamente objetos del tipo tsibble. También usaremos la librería leaflet que nos permite gestionar información geográfica y mapas. Esta librería suministra una interfaz para trabajar desde R con la librería en JavaScript Leaflet (ver [Leaflet]), ampliamente utilizada para visualizar información geográfica y mapas de forma interactiva.

6.1 Diagramas de barras interactivos

Usando ggplotly vamos a crear un gráfico interactivo con el mismo diagrama de barras de la sección 4.3. Como vemos, el gráfico se genera igual. Lo único que cambia es que el gráfico se almacena previamente en la variable p y después de dibuja con ggplotly. Observamos que cuando pasamos el ratón por encima de las barras nos aparece información adicional

p <- owid_country %>%  
  group_by(continent)  %>% 
  summarise(
    male=mean(na.omit(male_smokers)),
    female=mean(na.omit(female_smokers))) %>%
  pivot_longer(male:female, names_to = "sex", values_to = "smokers") %>%  
  ggplot(aes(x=continent,y=smokers,fill=sex)) +
    geom_bar(stat = "identity") 
ggplotly(p)

Figure 6.1: Diagrama de barras apilado usando geom_bar

6.2 Diagramas de cajas interactivos

Usando ggplotly vamos a crear un gráfico interactivo con el mismo diagrama de cajas de la sección 4.7. Observamos que cuando pasamos el ratón por encima de los puntos nos aparece información adicional y si nos situamos a la derecha de una caja nos sale información estadística de la distribución de valores.

p <- owid_country %>% 
  ggplot(aes(x=continent,y=gdp_per_capit,fill=continent,label=location)) + 
    geom_boxplot(outlier.shape = NA) +
    geom_jitter(shape=16, position=position_jitter(0.2))+
    theme(legend.position = "none")
ggplotly(p,tooltip=c("location","gdp_per_capit"))

Figure 6.2: Diagrama de cajas interactivos usando ggplotly

6.3 Diagramas de dispersión interactivos

Usando ggplotly vamos a crear un gráfico interactivo con el mismo diagrama de dispersión de la sección 4.8. Observamos que cuando pasamos el ratón por encima de los puntos nos aparece información adicional.

p <- owid_country %>% 
  mutate(gdp_per_capit=round(gdp_per_capit)) %>% 
  ggplot(aes(x=gdp_per_capit,y=life_expectancy,color=location)) + 
    geom_point() +
    scale_x_continuous(trans = 'log2')+
    theme(legend.position = "none")
  ggplotly(p)

Figure 6.3: Diagrama de puntos interactivos usando ggplotly

6.4 Gráficos de línea interactivos

A partir de un informe del 2022 del Oak Ridge National Laboratory vamos a estudiar el consumo de combustible según el tipo de coche y como aumenta dicho consumo con la velocidad. El dato que se estudia en el informe es cuantas millas recorre el coche usando un galón (3.786 litros). Vamos a hacer un gráfico de línea interactivo pasando el dato de la velocidad a km/h.

ConsumoVehiculos <- read.xlsx("../data/ConsumoVehiculos.xlsx",startRow = 6) %>%
  as_tibble() 
# Estructura de la tabla
str(ConsumoVehiculos)
## tibble [4 × 8] (S3: tbl_df/tbl/data.frame)
##  $ speed               : num [1:4] 45 55 65 75
##  $ Gasoline.Midsize.Car: num [1:4] 43 45 38 32
##  $ Gasoline.Small.SUV  : num [1:4] 37 36 30 26
##  $ Gasoline.Large.SUV  : num [1:4] 35 31 29 25
##  $ Diesel.Midsize.Car  : num [1:4] 57 55 45 37
##  $ Diesel.Small.SUV    : num [1:4] 48 45 36 30
##  $ Diesel.Large.SUV    : num [1:4] 48 40 35 29
##  $ Hybrid.Midsize.Car  : num [1:4] 55 46 38 33
p <- ConsumoVehiculos %>% 
  pivot_longer(Gasoline.Midsize.Car:Hybrid.Midsize.Car, names_to = "Car.Type", values_to = "Miles.Per.Gallon") %>% 
  mutate(`speed (km/h)`=speed*1.60934) %>%
  ggplot(aes(x=`speed (km/h)`,y=Miles.Per.Gallon,colour=Car.Type))+
  geom_line()+
  geom_point()
ggplotly(p)

Figure 6.4: Grafico de línea interactivo usando ggplotly

Observamos que el vehículo que más millas recorre por galón es el diesel de tamaño medio, y el que menos recorre es el SUV grande de gasolina. Los SUV recorren bastantes menos millas por galón que los coches convencionales y como es de esperar, cuanto más grandes son, menos millas recorren. El híbrido de tamaño medio tiene un comportamiento bastante mejor que el de gasolina de tamaño medio a velocidades bajas, pero a velocidades altas tienden a equipararse, e incluso a 120.7 km/h el convencional es algo mejor, seguramente porque a esas velocidades la batería ya no aporta nada y supone un peso adicional para el vehículo.

Además, para hacernos una idea de, como, en cada tipo de vehículo, afecta la velocidad al consumo de combustible, vamos a representar el porcentaje en que varía el consumo de combustible según vamos aumentando la velocidad desde los 72.4 km/h. Para ello tendremos en cuenta que el consumo es inversamente proporcional a la distancia recorrida por cada galón.

for(i in 2:ncol(ConsumoVehiculos)){
  for(j in seq(nrow(ConsumoVehiculos),1, by = -1)){
    ConsumoVehiculos[j,i] <- 100*(ConsumoVehiculos[1,i]/ConsumoVehiculos[j,i]-1)
  }
}

p <- ConsumoVehiculos %>% 
  pivot_longer(Gasoline.Midsize.Car:Hybrid.Midsize.Car, names_to = "Car.Type", values_to = "Percentaje.Variation.Fuel.Consumed") %>% 
  mutate(`speed (km/h)`=speed*1.60934) %>%
  ggplot(aes(x=`speed (km/h)`,y=Percentaje.Variation.Fuel.Consumed,colour=Car.Type))+
  geom_line()+
  geom_point()
ggplotly(p)

Figure 6.5: Grafico de línea interactivo usando ggplotly

Esta gráfica nos ilustra el fuerte aumento del consumo de combustible con el aumento de la velocidad. En el primer tramo, desde los 72.4 km/h hasta los 88.5 km/h, el SUV Grande Diesel y el Híbrido de tamaño medio son los que más suben el consumo (un 20%). Los coches más pequeños son los que mejor se comportan en este tramo y el de gasolina incluso disminuye el consumo. Cuando seguimos aumentando la velocidad todos los tipos de vehículos aumentan fuertemente el consumo en un rango que va desde un 34.4% en el caso del coche de gasolina de tamaño medio hasta un 66.6% en el caso de los híbridos.

Las conclusiones principales que se deprenden de estos datos son :

  1. Los coches convencionales son significativamente más eficientes que los SUV en el consumo de combustible.

  2. Los SUV grandes son menos eficientes que los SUV pequeños pero la diferencia entre ellos no es muy grande.

  3. En términos de consumo, los motores Diesel son más eficientes que los de gasolina, aunque cuando se aumenta la velocidad su consumo tiende a aumentar más que en los de gasolina.

  4. Los híbridos son significativamente más eficientes que los convencionales a bajas velocidades, pero a altas velocidades la batería no aporta nada, incluso puede empeorar el rendimiento.

  5. Reducir la velocidad es un factor determinante en la reducción del consumo de combustible.

6.5 Series temporales interactivas

Usando hchart vamos a crear un gráfico interactivo con las mismas series temporales ilustradas en la sección 5.2. Observamos que cuando pasamos el ratón por encima de la serie temporal nos aparece información adicional

owid_population <- read_csv("https://ctim.es/AEDV/data/owid_population.csv") %>%
  as_tibble() %>%
  filter(
    Entity == "World" | 
    Entity == "Europe" | 
    Entity == "Asia" | 
    Entity == "Africa")  
tsibble(
  date = owid_population$Year,
  population = owid_population$`Population (historical estimates)`,
  location = owid_population$Entity,
  index = date,
  key = location) %>% 
    hchart("line",hcaes(x = date, y = population, group = location))

Figure 6.6: Gráfico interactivo de series temporales usando hchart

6.6 Mapas de calor interactivos

Usando ggplotly vamos a crear un gráfico interactivo con el mismo mapa de calor ilustrado en la sección 4.13. Observamos que cuando pasamos el ratón por encima de las cuadrículas del mapa de calor nos aparece información adicional.

p <- sel_owid_country %>%
  pivot_longer(population:human_development_index, names_to = "indicator", values_to = "value") %>%
  ggplot(aes(indicator,location,fill=value)) + 
    geom_tile() + 
    scale_fill_gradientn(colors = brewer.pal(9, 'YlOrRd'))+
    theme(axis.text.x = element_text(angle = 45,hjust=1))
ggplotly(p, tooltip=c("indicator","location","value"))

Figure 6.7: Heatmap de algunos indicadores europeos normalizados diviendo por su máximo

6.7 Información geográfica

Con frecuencia, los datos que manejamos están vinculados a localizaciones geográficas (países, municipios, etc.) y en la exploración de estos datos, resulta de gran interés posicionar los datos en un gráfico, de acuerdo con su localización geográfica. Para ello, el gráfico debe incluir la localización geográfica de las regiones de interés. Hay diferentes tipos de formatos de objetos que permiten almacenar en disco esta información geográfica. Nosotros utilizaremos el formato geojson que puede interpretarse como una tabla de datos donde uno de los campos es especial y contiene las coordenadas de un polígono que delimita el borde (o contorno) de la región. Al leer un fichero en formato geojson se carga en un objeto de tipo SpatialPolygonsDataFrame.

Países del mundo

Veamos un primer ejemplo con la información geográfica de los países del mundo. La información geométrica de los bordes de los países se han obtenido, en el formato geojson del sitio web datahub, posteriormente, para simplificar la geometría de los bordes de los países y que el fichero ocupe menos y sea más ágil su manejo se redujo su tamaño usando la aplicación mapshaper.org. A continuación leemos el fichero usando la función geojson_read de la librería geojsonio. Como hemos comentado, hay un campo especial por cada país que contiene un polígono con el contorno del país. Para explorar el resto de campos de la tabla, la convertimos a tibble, al hacer esto, el campo especial con los datos geográficos desaparece. Como podemos observar, estos campos son el nombre del país y su código identificativo.

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_countries.geojson",  what = "sp")
geoj %>% as_tibble()
## # A tibble: 255 × 2
##    ADMIN                ISO_A3
##    <chr>                <chr> 
##  1 Aruba                ABW   
##  2 Afghanistan          AFG   
##  3 Angola               AGO   
##  4 Anguilla             AIA   
##  5 Albania              ALB   
##  6 Aland                ALA   
##  7 Andorra              AND   
##  8 United Arab Emirates ARE   
##  9 Argentina            ARG   
## 10 Armenia              ARM   
## # ℹ 245 more rows

Nuestro siguiente objetivo es mostrar un gráfico interactivo donde aparezcan los países y al pasar el ratón por encima de un país, aparezca su nombre y su código identificativo. para ello utilizaremos la librería leaflet que es una interfaz para R de un software de referencia para hacer gráficos interactivos en la web. Lo primero que hay que hacer es crear un vector con las etiquetas, en formato HTML, que queremos que aparezcan asociadas a cada país. Hay que tener en cuenta que en HTML para delimitar texto en negritas se utiliza <strong> y para hacer un salto de línea se utiliza <br>. Ademas hay que codificar el texto como HTML que es lo que hace la función htmltools::HTML. Posteriormente creamos el gráfico con la función leaflet y añadimos los polígonos de los contornos de los países con las etiquetas.

etiquetas <-paste("<strong> País: ",geoj$ADMIN ,"</strong><br>ISO: ",geoj$ISO_A3) %>% 
  lapply(htmltools::HTML)
geoj %>%
  leaflet() %>%  
  setView(lng = 5, lat = 22, zoom = 2) %>% 
  addPolygons(label = etiquetas,weight = 0.5)

Figure 6.8: Visualización interactiva de los países del mundo usando leaflet

6.7.1 Estados de los Estados Unidos

Ahora haremos los mismo para los estados de los Estados Unidos. Para ello leeremos los datos gráficos del sitio https://eric.clst.org/ que ha procesado y simplificado los datos obtenidos desde el United States Census Cartographic Boundary Files

geoj <- geojson_read("https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_040_00_20m.json",  what = "sp")
geoj %>% as_tibble()
## # A tibble: 52 × 5
##    GEO_ID      STATE NAME                 LSAD  CENSUSAREA
##    <chr>       <chr> <chr>                <chr>      <dbl>
##  1 0400000US04 04    Arizona              ""      113594. 
##  2 0400000US05 05    Arkansas             ""       52035. 
##  3 0400000US06 06    California           ""      155779. 
##  4 0400000US08 08    Colorado             ""      103642. 
##  5 0400000US09 09    Connecticut          ""        4842. 
##  6 0400000US11 11    District of Columbia ""          61.0
##  7 0400000US13 13    Georgia              ""       57513. 
##  8 0400000US15 15    Hawaii               ""        6423. 
##  9 0400000US17 17    Illinois             ""       55519. 
## 10 0400000US18 18    Indiana              ""       35826. 
## # ℹ 42 more rows

En el gráfico interactivo usamos como etiquetas los nombres de los estados:

etiquetas <-paste("<strong> State:<br>",geoj$NAME ,"</strong>") %>% 
  lapply(htmltools::HTML)
geoj %>%
  leaflet() %>%  
  setView(lng = -97, lat = 40, zoom = 4) %>% 
  addPolygons(label = etiquetas,weight = 0.5)

Figure 6.9: Visualización interactiva de los estados de USA usando leaflet

Municipios de las Islas Canarias

En este caso se ha utilizado el fichero con los datos geográficos publicados por el ISTAC.

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_canarias_municipios.geojson",  what = "sp")
geoj %>% as_tibble()
## # A tibble: 88 × 19
##    geocode geopadre etiqueta   notas         granularidad gcd_provincia gcd_isla
##    <chr>   <chr>    <chr>      <chr>         <chr>        <chr>         <chr>   
##  1 35001   ES705A22 Agaete     Ayuntamiento… MUNICIPIOS   ES701         ES705   
##  2 35002   ES705A32 Agüimes    Ayuntamiento… MUNICIPIOS   ES701         ES705   
##  3 35003   ES704A01 Antigua    Ayuntamiento… MUNICIPIOS   ES701         ES704   
##  4 35004   ES708A01 Arrecife   Ayuntamiento… MUNICIPIOS   ES701         ES708   
##  5 35005   ES705A23 Artenara   Ayuntamiento… MUNICIPIOS   ES701         ES705   
##  6 35006   ES705A10 Arucas     Ayuntamiento… MUNICIPIOS   ES701         ES705   
##  7 35007   ES704A01 Betancuria Ayuntamiento… MUNICIPIOS   ES701         ES704   
##  8 35008   ES705A21 Firgas     Ayuntamiento… MUNICIPIOS   ES701         ES705   
##  9 35009   ES705A22 Gáldar     Ayuntamiento… MUNICIPIOS   ES701         ES705   
## 10 35010   ES708A02 Haría      Ayuntamiento… MUNICIPIOS   ES701         ES708   
## # ℹ 78 more rows
## # ℹ 12 more variables: gcd_grancomarca <chr>, gcd_comarca <chr>, ign_sup <dbl>,
## #   ign_perim <dbl>, utm_x <dbl>, utm_y <dbl>, longitud <dbl>, latitud <dbl>,
## #   utm_x_capi <dbl>, utm_y_capi <dbl>, long_capi <dbl>, lati_capi <dbl>

Para cada municipio vamos a mostrar su nombre, su geocode, su latitud y su longitud:

etiquetas <-paste("<strong> Municipio: ",geoj$etiqueta ,"</strong><br>GEOCODE: ",geoj$geocode,
                  "<br>longitud: ",geoj$longitud,
                  "<br>llatitud: ",geoj$latitud) %>% 
  lapply(htmltools::HTML)
geoj %>%
  leaflet() %>%  
  addPolygons(label = etiquetas,weight = 0.5)

Figure 6.10: Visualización interactiva de los municipios de Canarias usando leaflet

Datos de España

Los datos geográficos de España se han obtenido a través de GADM

Autonomías

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_spain_autonomias.geojson",  what = "sp")
geoj %>% as_tibble()
## # A tibble: 18 × 11
##    GID_1  GID_0 COUNTRY NAME_1 VARNAME_1 NL_NAME_1 TYPE_1 ENGTYPE_1 CC_1  HASC_1
##    <chr>  <chr> <chr>   <chr>  <chr>     <chr>     <chr>  <chr>     <chr> <chr> 
##  1 ESP.1… ESP   Spain   Andal… Andalous… NA        Comun… Autonomo… 01    ES.AN 
##  2 ESP.2… ESP   Spain   Aragón Aragão|A… NA        Comun… Autonomo… 15    ES.AR 
##  3 ESP.3… ESP   Spain   Canta… Cantàbri… NA        Comun… Autonomo… 06    ES.CB 
##  4 ESP.4… ESP   Spain   Casti… Castela-… NA        Comun… Autonomo… 08    ES.CM 
##  5 ESP.5… ESP   Spain   Casti… Castilea… NA        Comun… Autonomo… 07    ES.CL 
##  6 ESP.6… ESP   Spain   Catal… Catalogn… NA        Comun… Autonomo… 09    ES.CT 
##  7 ESP.7… ESP   Spain   Ceuta… NA        NA        Ciuda… Autonomo… 19    ES.ML 
##  8 ESP.8… ESP   Spain   Comun… Madrid|C… NA        Comun… Autonomo… NA    ES.MD 
##  9 ESP.9… ESP   Spain   Comun… Communau… NA        Comun… Autonomo… 15    ES.NA 
## 10 ESP.1… ESP   Spain   Comun… Valencia… NA        Comun… Autonomo… 10    ES.VC 
## 11 ESP.1… ESP   Spain   Extre… Estremad… NA        Comun… Autonomo… 11    ES.EX 
## 12 ESP.1… ESP   Spain   Galic… Galice|G… NA        Comun… Autonomo… 12    ES.GA 
## 13 ESP.1… ESP   Spain   Islas… Balearic… NA        Comun… Autonomo… 04    ES.PM 
## 14 ESP.1… ESP   Spain   Islas… Canarias… NA        Comun… Autonomo… 05    ES.CN 
## 15 ESP.1… ESP   Spain   LaRio… Rioja     NA        Comun… Autonomo… 17    ES.LO 
## 16 ESP.1… ESP   Spain   PaísV… BasqueCo… NA        Comun… Autonomo… 16    ES.PV 
## 17 ESP.1… ESP   Spain   Princ… Astúrias… NA        Comun… Autonomo… 03    ES.AS 
## 18 ESP.1… ESP   Spain   Regió… Murcia|R… NA        Comun… Autonomo… 14    ES.MU 
## # ℹ 1 more variable: ISO_1 <chr>
etiquetas <-geoj$NAME_1 %>% 
  lapply(htmltools::HTML)
geoj %>%
  leaflet() %>%  
  addPolygons(label = etiquetas,weight = 0.5)

Figure 6.11: Visualización interactiva de las autonomías de España usando leaflet

Provincias

Vamos a mostrar las provincias de Andalucía:

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_spain_provincias.geojson",  what = "sp") %>%
  subset(NAME_1=="Andalucía")
geoj %>% as_tibble()
## # A tibble: 8 × 13
##   GID_2   GID_0 COUNTRY GID_1 NAME_1 NL_NAME_1 NAME_2 VARNAME_2 NL_NAME_2 TYPE_2
##   <chr>   <chr> <chr>   <chr> <chr>  <chr>     <chr>  <chr>     <chr>     <chr> 
## 1 ESP.1.… ESP   Spain   ESP.… Andal… NA        Almer… NA        NA        Provi…
## 2 ESP.1.… ESP   Spain   ESP.… Andal… NA        Cádiz  NA        NA        Provi…
## 3 ESP.1.… ESP   Spain   ESP.… Andal… NA        Córdo… NA        NA        Provi…
## 4 ESP.1.… ESP   Spain   ESP.… Andal… NA        Grana… NA        NA        Provi…
## 5 ESP.1.… ESP   Spain   ESP.… Andal… NA        Huelva NA        NA        Provi…
## 6 ESP.1.… ESP   Spain   ESP.… Andal… NA        Jaén   NA        NA        Provi…
## 7 ESP.1.… ESP   Spain   ESP.… Andal… NA        Málaga NA        NA        Provi…
## 8 ESP.1.… ESP   Spain   ESP.… Andal… NA        Sevil… NA        NA        Provi…
## # ℹ 3 more variables: ENGTYPE_2 <chr>, CC_2 <chr>, HASC_2 <chr>
 etiquetas <-geoj$NAME_2 %>% 
  lapply(htmltools::HTML)
geoj %>%
  leaflet() %>%  
  addPolygons(label = etiquetas,weight = 0.5)

Figure 6.12: Visualización interactiva de las provincias de Andalucía usando leaflet

En este caso, se ha filtrado la tabla, usando la función subset para que solo se dibujen las provincias de Andalucía

Municipios

Vamos ahora a mostrar los municipios de Andalucía:

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_spain_municipios.geojson",  what = "sp") %>%
  subset(NAME_1=="Andalucía")
geoj %>% as_tibble()
## # A tibble: 783 × 14
##    GID_4   GID_0 COUNTRY GID_1 NAME_1 GID_2 NAME_2 GID_3 NAME_3 NAME_4 VARNAME_4
##    <chr>   <chr> <chr>   <chr> <chr>  <chr> <chr>  <chr> <chr>  <chr>  <chr>    
##  1 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Albán… NA       
##  2 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Albox  NA       
##  3 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Alcón… NA       
##  4 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Arbol… NA       
##  5 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Armuñ… NA       
##  6 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Bacar… NA       
##  7 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Bayar… NA       
##  8 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Canto… NA       
##  9 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Cherc… NA       
## 10 ESP.1.… ESP   Spain   ESP.… Andal… ESP.… Almer… ESP.… n.a.(… Fines  NA       
## # ℹ 773 more rows
## # ℹ 3 more variables: TYPE_4 <chr>, ENGTYPE_4 <chr>, CC_4 <chr>
 etiquetas <- geoj$NAME_4 %>% 
  lapply(htmltools::HTML)
geoj %>%
  leaflet() %>%  
  addPolygons(label = etiquetas,weight = 0.5)

Figure 6.13: Visualización interactiva de los municipios de Andalucía usando leaflet

6.8 Mapas con OpenStreetMap

Leaflet utiliza, por defecto, los mapas diseñados por OpenStreetMap para crear mapas. En primer lugar vamos a crear un mapa con las Islas Canarias donde aparezca una etiqueta en la posición donde se encuentran los municipios. Para ello vamos a leer los datos geográficos de los municipios canarios:

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_canarias_municipios.geojson",  what = "sp")
geoj_ti <- geoj %>% 
  as_tibble() %>% 
  rename(nombre=etiqueta) %>%
  select(nombre,latitud,longitud)
geoj_ti %>%
  print(n=3)
## # A tibble: 88 × 3
##   nombre  latitud longitud
##   <chr>     <dbl>    <dbl>
## 1 Agaete     28.1    -15.7
## 2 Agüimes    27.9    -15.5
## 3 Antigua    28.4    -13.9
## # ℹ 85 more rows

En el tibble geoj_ti hemos seleccionado el nombre, la longitud y la latitud de los municipios que usaremos ahora para crear el mapa:

etiquetas <- paste("<strong>",geoj_ti$nombre,"</strong>") %>% 
  lapply(htmltools::HTML)
geoj %>% 
  leaflet() %>% # creación gráfico a partir de geoj
  addTiles() %>% # añadimos mapa
  addMarkers( #  añadimos marcadores
    geoj_ti$longitud, # longitud marcador
    geoj_ti$latitud,# latitud marcador 
    label = etiquetas, # etiquetas marcadores
    clusterOptions = markerClusterOptions() # opción para agrupar marcadores
  )

Figure 6.14: Mapa interactivo con marcadores en la localización de los municipios canarios

A continuación vamos a crear un mapa con círculos cuya área sea proporcional a la superficie de los municipios canarios. Como la superficie de los municipios canarios no está en el objeto geométrico geoj tenemos que buscarlos en otra tabla donde se encuentre y vincularlo. Como geoj no contiene el identificador del INE del municipio tenemos que comparar los nombres de los municipios para vincular los datos

source("utilidades.R")
# Leemos un fichero que contiene la superficie y el código INE de los municipios 
istac_municipios <- read.xlsx("https://ctim.es/AEDV/data/istac_municipios_ine_codes.xlsx") %>%
  as_tibble()
istac_municipios %>% 
  print(n=3)
## # A tibble: 88 × 6
##   ine_code nombre  nombre2 nombre3 isla         superficie
##   <chr>    <chr>   <chr>   <chr>   <chr>             <dbl>
## 1 38001    Adeje   Adeje   Adeje   Tenerife          106. 
## 2 35001    Agaete  Agaete  Agaete  Gran Canaria       45.5
## 3 35002    Agüimes Agüimes Agüimes Gran Canaria       79.3
## # ℹ 85 more rows
# Comparamos el nombre del municipio en `geoj_ti` con los nombres  en `istac_municipios`
index <- LeftJoinNearestString(geoj_ti%>%select(nombre),istac_municipios%>%select(nombre:nombre3))
index  %>% 
  filter(dis>0) %>% 
  arrange(desc(dis))  %>% 
  print(n=100)
## # A tibble: 5 × 4
##     pos value1                     value2                       dis
##   <int> <chr>                      <chr>                      <dbl>
## 1    50 El Pinar de El Hierro      Pinar del Hierro (El)         10
## 2    39 La Matanza de Acentejo     Matanza de Acentejo (La)       8
## 3    42 La Victoria de Acentejo    Victoria de Acentejo (La)      8
## 4    61 San Sebastián de La Gomera San Sebastián de la Gomera     1
## 5    63 Santa Cruz de La Palma     Santa Cruz de la Palma         1
# Después de comprobar que las correspondencias son correctos creamos el ine_code para `geoj_ti`
ine_code <- integer(length(geoj_ti$nombre))
for(i in 1:length(ine_code) ){
  ine_code[i] <- istac_municipios$ine_code[index$pos[i]]
}
geoj_ti$ine_code <- ine_code
# Hacemos un left_join de `geoj_ti`y `istac_municipios` usando `ine_code`
join <- left_join(geoj_ti,istac_municipios,by = "ine_code")
join %>%
  print(n=3)
## # A tibble: 88 × 9
##   nombre.x latitud longitud ine_code nombre.y nombre2 nombre3 isla    superficie
##   <chr>      <dbl>    <dbl> <chr>    <chr>    <chr>   <chr>   <chr>        <dbl>
## 1 Agaete      28.1    -15.7 35001    Agaete   Agaete  Agaete  Gran C…       45.5
## 2 Agüimes     27.9    -15.5 35002    Agüimes  Agüimes Agüimes Gran C…       79.3
## 3 Antigua     28.4    -13.9 35003    Antigua  Antigua Antigua Fuerte…      251. 
## # ℹ 85 more rows

Finalmente creamos el mapa con los círculos, en las etiquetas ponemos como nombre del municipio join$nombre3 que es el campo que contiene el nombre corto del municipio.

etiquetas <- paste("<strong>",join$nombre3,"</strong><br/>",join$superficie," Km2") %>% 
  lapply(htmltools::HTML)
geoj %>% 
  leaflet() %>% # creación gráfico a partir de geoj
  addTiles() %>% # añadimos mapa
  addCircles( #  añadimos círculos
    lng = join$longitud, # longitud círculos
    lat = join$latitud, # latitud círculos 
    weight = 1, # grosor borde exterior círculos 
    radius = sqrt(join$superficie) * 300, # radio del círculo 
    label= etiquetas #etiquetas 
  )

Figure 6.15: Mapa interactivo con círculos proporcionales a la superficie de los municipios canarios

Ahora creamos un mapa, centrado en Gran Canaria, donde aparecen los límites de cada municipio combinado con el mapa.

etiquetas <- paste("<strong>",join$nombre3,"</strong><br/>",join$superficie," Km2") %>% 
  lapply(htmltools::HTML)
geoj %>%
  leaflet() %>%  # creación gráfico a partir de geoj
  setView(lng = -15.6, lat = 27.95, zoom = 10) %>% # posición central y zoom 
  addTiles() %>% # añadimos mapa
  addPolygons( # añadimos límites municipios 
    color = "blue", # color borde municipio
    weight = 2, # grosor borde municipio 
    dashArray = "3", # línea borde municipio entrecortada
    fillOpacity = 0., # el interior del polígono del municipio es transparente 
    highlightOptions = highlightOptions( #opciones al pasar el ratón por encima
      color = "black", # color del realzado
      weight = 4, # grosor borde realzado 
      dashArray = "", # línea borde municipio continua
      fillOpacity = 0., # el interior del polígono del municipio es transparente 
      bringToFront = TRUE # el efecto del realzado se superpone
    ),
    label = etiquetas # etiquetas que se muestran en el realzado de los municipios. 
  )

Figure 6.16: Visualización interactiva del mapa con los límites dibujados de los municipios de Canarias usando leaflet

6.9 Mapas coropléticos

Un mapa coroplético (choropleth map) es un gráfico dividido en zonas (por ejemplo áreas geográficas) en el que cada zona se colorea de forma distinta en función del valor de una variable estadística. Para ilustrar este concepto dibujaremos un gráfico con los países del mundo, utilizando como variable estadística su PIB por habitante. En primer lugar, leemos la información geográfica:

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_countries.geojson",  what = "sp")
geoj_ti <- geoj %>% as_tibble()
geoj_ti
## # A tibble: 255 × 2
##    ADMIN                ISO_A3
##    <chr>                <chr> 
##  1 Aruba                ABW   
##  2 Afghanistan          AFG   
##  3 Angola               AGO   
##  4 Anguilla             AIA   
##  5 Albania              ALB   
##  6 Aland                ALA   
##  7 Andorra              AND   
##  8 United Arab Emirates ARE   
##  9 Argentina            ARG   
## 10 Armenia              ARM   
## # ℹ 245 more rows

A continuación, como el dato de PIB por habitante no está en esta tabla, lo tomaremos de la tabla donde está,owid_country, y haremos unleft_join` con esta tabla usando como campo común el código ISO del país (que tiene diferente nombre de campo en las dos tablas):

join <- left_join(geoj_ti,owid_country,by = c("ISO_A3" = "iso_code"))
join %>%
  print(n=5)
## # A tibble: 255 × 18
##   ADMIN       ISO_A3 location    continent population median_age life_expectancy
##   <chr>       <chr>  <chr>       <chr>          <dbl>      <dbl>           <dbl>
## 1 Aruba       ABW    Aruba       North Am…     106459       41.2            76.3
## 2 Afghanistan AFG    Afghanistan Asia        41128772       18.6            64.8
## 3 Angola      AGO    Angola      Africa      35588996       16.8            61.2
## 4 Anguilla    AIA    Anguilla    North Am…      15877       NA              81.9
## 5 Albania     ALB    Albania     Europe       2842318       38              78.6
## # ℹ 250 more rows
## # ℹ 11 more variables: aged_65_older <dbl>, aged_70_older <dbl>,
## #   gdp_per_capit <dbl>, extreme_poverty <dbl>, cardiovasc_death_rat <dbl>,
## #   diabetes_prevalence <dbl>, female_smokers <dbl>, male_smokers <dbl>,
## #   handwashing_facilities <dbl>, hospital_beds_per_thousand <dbl>,
## #   human_development_index <dbl>

A continuación generamos el gráfico interactivo y después explicaremos los elementos que aparecen nuevos:

etiquetas <-paste("<strong> ",join$ADMIN ,"</strong><br>PIB/CAPITA: ",round(join$gdp_per_capit)) %>% 
  lapply(htmltools::HTML)
pal <- colorQuantile("YlOrRd", join$gdp_per_capit, n = 9)
geoj %>%
  leaflet() %>%  
  setView(lng = 5, lat = 22, zoom = 2) %>% 
  addPolygons(
    fillColor = ~pal(join$gdp_per_capit), 
    weight = 2,
    opacity = 1,
    color = "white",
    dashArray = "3",
    fillOpacity = 0.7,
    highlightOptions = highlightOptions( 
      weight = 2,
      color = rgb(0.2,0.2,0.2),
      dashArray = "",
      fillOpacity = 0.7,
      bringToFront = TRUE
    ),
    label = etiquetas 
  ) %>% 
  addLegend("bottomleft", pal = pal, values = join$gdp_per_capit,
    title = "PIB/habit.",
    labFormat = function(type, cuts, p) {
          n = length(cuts) 
          as.character(round((as.integer(cuts)[-n] + as.integer(cuts)[-1])/2))
        },
    opacity = 1
  )

Figure 6.17: Visualización interactiva del PIB por habitante en los países del mundo

La instrucción pal <- colorQuantile("YlOrRd", join$gdp_per_capit, n = 9) genera una tabla de colores asociando los percentiles de los valores del PIB por habitante con la tabla de colores “YlOrRd”.

La instrucción fillColor = ~pal(join$gdp_per_capit) utiliza la tabla de colores generada para asignar colores a los países.

La instrucción highlightOptions = ... produce que cuando el ratón se sitúa por encima de un país, se destaca el país para que se vea más claro el contorno del país seleccionado. El resto de los diferentes elementos que aparecen son parámetros de las diferentes funciones.

La instrucción addLegend(...) posiciona una leyenda en la parte inferior izquierda del gráfico con los colores de la paleta y el valor numérico de referencia para ese color.

Referencias

[Ca] Cartography Vectors.

[Hi21] Asha Hill. 9 Useful R Data Visualization Packages for Data Visualization, 2021.

[Ka20] Rob Kabacoff. Data Visualization with R, 2020.

[Leaflet] Leaflet for R.

[Open] OpenDataSoft

[Rc] R CODER. R CHARTS.

[Sthda] STHDA Statistical tools for high-throughput data analysis.

[Ho] Yan Holtz. The R Graph Gallery.

[DataNovia] Highchart Lessons. Datanovia.