6 Visualización dinámica
Fecha última actualización: 2024-11-07
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)
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 o en cuadros de mandos (como veremos en el tema siguiente). Utilizaremos las siguientes librerías para la visualización dinámica de datos:
plotly
: La libreríaplotly
en R es una adaptación de la librería plotly.js originalmente desarrollada en javascript. En R,plotly
fue creada como un paquete que combina las capacidades de plotly.js con la facilidad y flexibilidad de R, y comenzó a ganar popularidad por sus funcionalidades interactivas, que iban más allá de lo que las bibliotecas estándar como ggplot2 podían ofrecer.plotly
en R destaca por su integración con ggplot2, permitiendo convertir gráficos estáticos de ggplot2 en gráficos interactivos con una sola línea de código mediante la funciónggplotly()
.highcharter
: La libreríahighcharter
en R es una interfaz para utilizar la biblioteca de gráficos JavaScript llamadaHighcharts
que es una de las librerías de gráficos en JavaScript más populares en la web y permite crear gráficos interactivos de gran calidad.leaflet
: La librería leaflet en R es una interfaz para usar la popular biblioteca de mapas interactivos de JavaScript llamada Leaflet.js. El paquete permite a los usuarios crear mapas interactivos y visualizar información geográfica dentro de R usando funciones amigables que envuelven el código JavaScript subyacente de Leaflet.js
Estas 3 librerías que vamos a usar tienen la importante característica de estar adaptadas para integrar sus gráficos en cuadros de mandos, como veremos en el siguiente tema.
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)
6.2 Gráficos circulares interactivos
La librería plotly
no solo sirve para hacer dinámicos gráficos generados con ggplot
, plotly
tiene sus propias funciones de visualización como plot_ly
que usaremos para hacer un gráfico circular
owid_country %>%
group_by(continent) %>%
dplyr::summarise(population=sum(population)) %>%
plotly::plot_ly(
labels = ~continent,
values = ~population,
textinfo='label+percent',
insidetextorientation='radial'
) %>%
add_pie() %>%
hide_legend()
6.3 Gráficos de donuts interactivos
Vamos a hacer un gráfico de donuts con los mismos datos
owid_country %>%
group_by(continent) %>%
dplyr::summarise(population=sum(population)) %>%
plotly::plot_ly(
labels = ~continent,
values = ~population,
textinfo='label+percent',
insidetextorientation='radial'
) %>%
add_pie(hole=0.4) %>%
hide_legend()
6.4 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"))
Como observamos en el código anterior, con la opción tooltip
podemos seleccionar los campos que aparecen en el desplegable. Además es posible formatear el contenido del desplegable. A continuación haremos el mismo gráfico cambiando el texto del desplegable (<br>
es la instrucción en HTML para hacer un cambio de línea (retorno de carro)) :
p <- owid_country %>%
ggplot(aes(x=continent,y=gdp_per_capit,fill=continent,
text = paste('País: ', location,
'<br>PIB per capita: ', gdp_per_capit))
) +
geom_boxplot(outlier.shape = NA) +
geom_jitter(shape=16, position=position_jitter(0.2))+
theme(legend.position = "none")
ggplotly(p,tooltip=c("text"))
6.5 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=continent,label=location)) +
geom_point() +
scale_x_continuous(trans = 'log2')+
theme(legend.position = "none")
ggplotly(p)
6.6 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)
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)
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 :
Los coches convencionales son significativamente más eficientes que los SUV en el consumo de combustible.
Los SUV grandes son menos eficientes que los SUV pequeños pero la diferencia entre ellos no es muy grande.
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.
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.
Reducir la velocidad es un factor determinante en la reducción del consumo de combustible.
6.7 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))
6.8 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"))
6.9 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)
6.9.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)
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)
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)
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)
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)
6.10 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
)
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 × 5
## pos1 pos2 value1 value2 dis
## <int> <dbl> <chr> <chr> <dbl>
## 1 88 50 El Pinar de El Hierro Pinar del Hierro (El) 10
## 2 59 39 La Matanza de Acentejo Matanza de Acentejo (La) 8
## 3 85 42 La Victoria de Acentejo Victoria de Acentejo (La) 8
## 4 70 61 San Sebastián de La Gomera San Sebastián de la Gomera 1
## 5 71 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$pos2[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
)
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.
)
6.11 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 un
left_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):
## # 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
)
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.