6 Dynamic visualization of data

Install/load libraries/used data

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

In the dynamic visualization the user can interact with the graphs by hovering the mouse over the graph. This is of great interest for presenting data, especially when the data is presented on web pages as html files. We will use various libraries such as plotly that allows us to create an interactive graph of some objects created with ggplot, this makes our task much easier because the code is identical to the one that generates the graph with ggplot, the only thing that changes is the call when drawing the graph that is made with the ggplotly function. For the interactive visualization of time series we will use the highcharter library that allows us to directly manage objects of the tsibble type. We will also use the leaflet library that allows us to manage geographic information and maps. This library provides an interface to work from R with the Leaflet JavaScript library (see [Leaflet]), widely used to display geographic information and maps in a interactive.

6.1 Interactive bar charts

Using ggplotly we will create an interactive graph with the same bar plot from the 4.3 section. As we see, the graph is generated the same. The only thing that changes is that the plot is previously stored in the variable p and then drawn with ggplotly. We observe that when we move the mouse over the bars, additional information appears

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: Stacked bar chart using geom_bar

6.2 Interactive Box Plots

Using ggplotly we will create an interactive graph with the same boxplot from the 4.7 section. We observe that when we move the mouse over the points, additional information appears and if we move to the right of a box, statistical information on the distribution of values appears.

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: Interactive boxplot using ggplotly

6.3 Interactive Scatterplots

Using ggplotly we will create an interactive graph with the same scatterplot from the 4.8 section. We observe that when we move the mouse over the points, additional information appears.

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: Interactive point plot using ggplotly

6.4 Interactive line charts

Based on a 2022 report from Oak Ridge National Laboratory we are going to study fuel consumption depending on the type of car and how such consumption increases with speed. The data studied in the report correspond to the miles the car travels using one gallon (3,786 liters). We are going to make an interactive line graph by passing the speed data to km/h.

VehicleConsumption <- read.xlsx("../data/ConsumoVehiculos.xlsx",startRow = 6) %>%
   as_tibble()
# Table structure
str(VehicleConsumption)
## 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 <- VehicleConsumption %>%
   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: Interactive line plot using ggplotly

We observe that the vehicle that travels the most miles per gallon is the mid-size diesel, and the one that travels the least is the large gasoline SUV. SUVs travel significantly fewer miles per gallon than conventional cars and as expected, the larger they are, the fewer miles they travel. The mid-size hybrid behaves much better than the mid-size gasoline one at low speeds, but at high speeds they tend to equalize, and even at 120.7 km/h the conventional one is somewhat better, probably because at those speeds the battery does not contribute to provide energy and represents additional weight for the vehicle.

Furthermore, to get an idea of how, in each type of vehicle, speed affects fuel consumption, we are going to represent the percentage in which fuel consumption varies as we increase speed from 72.4 km/h. To do this, we will take into account that consumption is inversely proportional to the distance traveled for each gallon.

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

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

Figure 6.5: Interactive line plot using ggplotly

This graph illustrates the strong increase in fuel consumption with increasing speed. In the first section, from 72.4 km/h to 88.5 km/h, the Large Diesel SUV and the mid-size Hybrid are the ones that increase consumption the most (20%). The smallest cars are the ones that behave best in this section and the gasoline one even reduces consumption. When we continue to increase speed, all types of vehicles sharply increase consumption in a range that goes from 34.4% in the case of medium-sized gasoline cars to 66.6% in the case of hybrids.

The main conclusions drawn from these data are:

  1. Conventional cars are significantly more fuel efficient than SUVs.

  2. Large SUVs are less efficient than small SUVs but the difference between them is not very big.

  3. In terms of consumption, diesel engines are more efficient than gasoline engines, although when speed is increased their consumption tends to increase more than gasoline engines.

  4. Hybrids are significantly more efficient than conventional ones at low speeds, but at high speeds the battery does not contribute to provide energy which deteriorates the performance.

  5. Reducing speed is a determining factor in reducing fuel consumption.

6.5 Interactive time series

Using hchart we will create an interactive chart with the same time series illustrated in the 5.2 section. We observe that when we move the mouse over the time series, additional information appears

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: Interactive time series chart using hchart

6.6 Interactive heat maps

Using ggplotly we will create an interactive graph with the same heatmap illustrated in the 4.13 section. We notice that when we move the mouse over the heat map grids, additional information appears.

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 of some normalized European indicators dividing by their maximum

6.7 Geographic information

Frequently, the data we handle is linked to geographic locations (countries, municipalities, etc.) and when exploring this data, it is of great interest to position the data in a graph, according to its geographic location. To do this, the graph must include the geographical location of the regions of interest. There are different types of object formats that allow this geographic information to be stored on disk. We will use the geojson format which can be interpreted as a data table where one of the fields is special and contains the coordinates of a polygon that delimits the edge (or contour) of the region. When reading a file in geojson format, it is loaded into an object of type SpatialPolygonsDataFrame.

Countries of the world

Let’s see a first example with geographic information of the countries of the world. The geometric information of the borders of the countries has been obtained, in the geojson format, from the website datahub, subsequently, we simplify the geometry of the borders of the countries and we reduce the file size using the application mapshaper.org. Next we read the file using the geojson_read function of the geojsonio library. As we have mentioned, there is a special field for each country which contains a polygon with the outline of the country. To explore the rest of the fields in the table, we convert it to tibble; by doing this, the special field with the geographic data disappears. As we can observe, these fields are the name of the country and its identification code.

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

Our next objective is to show an interactive graph where the countries appear and when passing the mouse over a country, its name and identification code appear. We will use the leaflet library which is an interface for R from a reference software to make interactive graphics on the web. The first thing to do is to create a vector with the labels, in HTML format, that we want to appear associated to each country. It must be taken into account that in HTML to delimit bold text, we use the code <strong> and to make a line break we use the code <br>. To encode the whole text as HTML we use the htmltools::HTML function. Next, we create the graph with the leaflet function and add the polygons of country outlines including the labels.

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

Figure 6.8: Interactive visualization of the countries of the world using leaflet

6.7.1 States of the United States

Now we will do the same for the states of the United States. To do this we will read the graphic data from the site https://eric.clst.org/ that has processed and simplified the data obtained from the 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

In the interactive graph we use the names of the states as tags:

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

Figure 6.9: Interactive visualization of USA states using leaflet

Municipalities of the Canary Islands

In this case, the file with the geographical data published by ISTAC has been used.

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>

For each municipality we are going to show its name, its geocode, its latitude and its longitude:

tags <-paste("<strong> Municipality: ",geoj$tag ,"</strong><br>GEOCODE: ",geoj$geocode,
                   "<br> longitude ",geoj$longitud,
                   "<br>latitude: ",geoj$latitud) %>%
   lapply(htmltools::HTML)
geoj %>%
   leaflet() %>%
   addPolygons(label = tags,weight = 0.5)

Figure 6.10: Interactive visualization of the municipalities of the Canary Islands using leaflet

Data from Spain

The geographical data of Spain have been obtained through GADM

Autonomies

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>
tags <-geoj$NAME_1 %>%
   lapply(htmltools::HTML)
geoj %>%
   leaflet() %>%
   addPolygons(label = tags,weight = 0.5)

Figure 6.11: Interactive visualization of the autonomies of Spain using leaflet

Provinces

We are going to show the provinces of 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>
  tags <-geoj$NAME_2 %>%
   lapply(htmltools::HTML)
geoj %>%
   leaflet() %>%
   addPolygons(label = tags,weight = 0.5)

Figure 6.12: Interactive visualization of the provinces of Andalucía using leaflet

In this case, the table has been filtered, using the subset function so that only the provinces of Andalucía are drawn

Municipalities

Now let’s show the municipalities of 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>
  tags <- geoj$NAME_4 %>%
   lapply(htmltools::HTML)
geoj %>%
   leaflet() %>%
   addPolygons(label = tags,weight = 0.5)

Figure 6.13: Interactive visualization of the municipalities of Andalucía using leaflet

6.8 Maps with OpenStreetMap

Leaflet uses, by default, maps designed by OpenStreetMap to create maps. First of all, we are going to create a map with the Canary Islands where a label appears in the position where the municipalities are located. To do this, we are going to read the geographical data of the Canarian municipalities:

geoj <- geojson_read("https://ctim.es/AEDV/data/geo_canarias_municipios.geojson", what = "sp")
geoj_ti <- geoj %>%
   as_tibble() %>%
   rename(name=etiqueta) %>%
   select(name,latitud,longitud)
geoj_ti %>%
   print(n=3)
## # A tibble: 88 × 3
##   name    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

In the geoj_ti tibble we have selected the name, longitude and latitude of the municipalities that we will now use to create the map:

tags <- paste("<strong>",geoj_ti$name,"</strong>") %>%
   lapply(htmltools::HTML)
geoj %>%
   leaflet() %>% # creating chart from geoj
   addTiles() %>% # add map
   addMarkers( # add markers
     geoj_ti$longitud, # marker longitude
     geoj_ti$latitud,# latitude marker
     label = tags, # labels markers
     clusterOptions = markerClusterOptions() # option to group markers
   )

Figure 6.14: Interactive map with markers in the location of the Canarian municipalities

Next we are going to create a map with circles whose area is proportional to the surface of the Canary Islands municipalities. As the surface of the Canary Islands municipalities is not in the geometric object geoj we have to look for them in another table where it is found and link it. Since geoj does not contain the INE identifier of the municipality, we have to compare the names of the municipalities to link the data

source("utilidades.R")
# We read a file that contains the surface area and the INE code of the municipalities
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
# We compare the name of the municipality in `geoj_ti` with the names in `istac_municipios`
index <- LeftJoinNearestString(geoj_ti%>%select(name),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
# After checking that the correspondences are correct we create the ine_code for `geoj_ti`
ine_code <- integer(length(geoj_ti$name))
for(i in 1:length(ine_code) ){
   ine_code[i] <- istac_municipios$ine_code[index$pos[i]]
}
geoj_ti$ine_code <- ine_code
# We make a left_join of `geoj_ti` and `istac_municipios` using `ine_code`
join <- left_join(geoj_ti,istac_municipios,by = "ine_code")
join %>%
   print(n=3)
## # A tibble: 88 × 9
##   name    latitud longitud ine_code nombre  nombre2 nombre3 isla      superficie
##   <chr>     <dbl>    <dbl> <chr>    <chr>   <chr>   <chr>   <chr>          <dbl>
## 1 Agaete     28.1    -15.7 35001    Agaete  Agaete  Agaete  Gran Can…       45.5
## 2 Agüimes    27.9    -15.5 35002    Agüimes Agüimes Agüimes Gran Can…       79.3
## 3 Antigua    28.4    -13.9 35003    Antigua Antigua Antigua Fuerteve…      251. 
## # ℹ 85 more rows

Finally we create the map with the circles, in the labels we put join$nombre3 as the name of the municipality, which is the field that contains the short name of the municipality.

tags <- paste("<strong>",join$nombre3,"</strong><br/>",join$superficie," Km2") %>%
   lapply(htmltools::HTML)
geoj %>%
   leaflet() %>% # creating chart from geoj
   addTiles() %>% # add map
   addCircles( # add circles
     lng = join$longitud, # longitude circles
     lat = join$latitud, # latitude circles
     weight = 1, # thickness outer edge circles
     radius = sqrt(join$superficie) * 300, # radius of the circle
     label= tags #labels
   )

Figure 6.15: Interactive map with circles proportional to the surface of the Canarian municipalities

Now we create a map, centered on Gran Canaria, where the limits of each municipality appear combined with the map.

tags <- paste("<strong>",join$nombre3,"</strong><br/>",join$superficie," Km2") %>%
   lapply(htmltools::HTML)
geoj %>%
   leaflet() %>% # creating chart from geoj
   setView(lng = -15.6, lat = 27.95, zoom = 10) %>% # center position and zoom
   addTiles() %>% # add map
   addPolygons( # add municipal limits
     color = "blue", # municipality border color
     weight = 2, # municipality border thickness
     dashArray = "3", # dashed municipality border line
     fillOpacity = 0., # the interior of the municipality polygon is transparent
     highlightOptions = highlightOptions( #hover options
       color = "black", # highlight color
       weight = 4, # raised border thickness
       dashArray = "", # continuous municipality border line
       fillOpacity = 0., # the interior of the municipality polygon is transparent
       bringToFront = TRUE # the highlight effect is overlaid
     ),
     label = tags # labels that are displayed in the highlight of the municipalities.
   )

Figure 6.16: Interactive visualization of the map with the drawn limits of the municipalities of the Canary Islands using leaflet

6.9 Choropleth maps

A choropleth map is a graph divided into different parts (for example geographic areas) in which each part is colored differently depending on the value of a numerical variable. To illustrate this concept we will draw a graph with the countries of the world, using their GDP per inhabitant as numerical variable. First of all, we read the geographical information:

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

Next, since the GDP per capita data is not in this table, we will take it from the table owid_country, and we will do a left_join with this table using as common field the ISO country code (which has a different field name in the two tables):

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>

Next we generate the choropleth map and then we will explain the new elements that appear:

tags <-paste("<strong> ",join$ADMIN ,"</strong><br>GDP/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 = tags
   ) %>%
   addLegend("bottomleft", pal = pal, values = join$gdp_per_capit,
     title = "GDP/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: Interactive visualization of GDP per capita in the countries of the world

The statement pal <- colorQuantile("YlOrRd", join$gdp_per_capit, n = 9) generates a color palette associating the percentiles of the GDP per capita values with the “YlOrRd” color chart.

The statement fillColor = ~pal(join$gdp_per_capit) uses the color palette generated to assign colors to countries.

The highlightOptions = ... instruction causes that when the mouse is hovered over a country, the boundary of the country is highlighted. The rest of the different elements that appear are parameters of the different functions.

The addLegend(...) statement positions a legend at the bottom left of the chart with the palette colors and the reference numeric value for that color.

References

[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.