Interactive Africa map with ggigraph

Author

Dhafer Malouche

Introduction

In this short tutorial, I will show you how to build the map of Africa using the ggiraph package. This powerful tool enables you to create dynamic ggplot graphs with added functionalities like tooltips, hover effects, and JavaScript actions. Moreover, when used in shiny applications, the package allows for the selection of graphical elements.

For more detailed information about this package, you can visit the official website at https://davidgohel.github.io/ggiraph/.

Step 1 (packages)

To begin, we need to load the necessary packages. Before that, make sure you have installed them. Here’s an example of how to load the required packages:

> library(sp)
> library(sf)
> library(ggplot2)
> library(ggiraph)
> library(ggthemes)
> library("maptools")
> library("mapproj")
> library("maps")
> library(rnaturalearth)
> library(tidyverse)
> library(dplyr)
> library(janitor)

Step 2 (map data)

Now, let’s load the necessary maps. We’ll begin with the World map and then filter it to obtain the map of Africa. For this purpose, we’ll utilize the rnaturalearth package, which offers map data that can be seamlessly used with other R packages.

 world <- sf::st_as_sf(countries110)
world <- world %>%clean_names()
africa <- dplyr::filter(world, region_un=='Africa')%>%
  st_transform(crs="+proj=laea +lon_0=18.984375")

Step 3 (data preparation)

In this example, our focus is to represent the growth rate of GDP per capita in African countries over a span of 10 years (from 2021 to 2011). To accomplish this, we will utilize World Bank data and the specific indicator NY.GDP.PCAP.CD. In order to proceed, we will require the WDI package in R.

dt<-WDI::WDI(indicator = c("NY.GDP.PCAP.CD"),start = 2010,end=2021,extra = T)
dt<-dt%>%filter(year%in%c(2011,2021))
dt<-dt%>%dplyr::filter(year%in%c(2011,2021))
dt<-dt%>%dplyr::filter(iso3c%in%africa$iso_a3)%>%
  dplyr::select(iso3c,year,NY.GDP.PCAP.CD)
dt<-dt%>%pivot_wider(id_cols = c('iso3c'),names_from = 'year',values_from = 'NY.GDP.PCAP.CD',names_prefix = 'y')
dt%>%head()
# A tibble: 6 × 3
  iso3c y2021 y2011
  <chr> <dbl> <dbl>
1 DZA   3691. 5473.
2 AGO   1954. 4511.
3 BEN   1319. 1099.
4 BWA   6805. 7081.
5 BFA    893.  728.
6 BDI    221.  236.

We will calculate the growth rate of GDP per capita between the years 2011 and 2021.

dt=dt%>%mutate(chg_rt=(y2021-y2011)/y2011)
dt%>%head()
# A tibble: 6 × 4
  iso3c y2021 y2011  chg_rt
  <chr> <dbl> <dbl>   <dbl>
1 DZA   3691. 5473. -0.326 
2 AGO   1954. 4511. -0.567 
3 BEN   1319. 1099.  0.200 
4 BWA   6805. 7081. -0.0389
5 BFA    893.  728.  0.227 
6 BDI    221.  236. -0.0633

Step 4 (map)

  • We will add the newly created variable to the ‘africa’ dataset.
africa<-africa%>%left_join(dt,by=c("iso_a3"="iso3c"))
  • We create the data for the map
africa.centers <- st_centroid(africa)

africa.spdf <- methods::as(africa, 'Spatial')
africa.spdf@data$id <- row.names(africa.spdf@data)

africa.tidy <- broom::tidy(africa.spdf)

africa.tidy <- dplyr::left_join(africa.tidy, 
                                africa.spdf@data, by='id')

africa.tidy <- africa.tidy %>% 
  mutate(labs=ifelse(is.na(chg_rt)==T,NA,
                     paste0(round(100*chg_rt,1),"%")))%>%
  mutate(chg_rt=100*chg_rt)
  • Pop-ups:
africa.tidy<-africa.tidy%>%
  mutate(tip=ifelse(is.na(chg_rt)==T,
                    paste0("<b>",name,"</b><br>","Data not available"),
                    paste0("<b>",name,"</b><br>",labs)))
  • The map
g <- ggplot(africa.tidy) +
  geom_polygon_interactive(
    color='black',size=.5,
    aes(long, lat, group=group, fill=chg_rt,
        tooltip=tip))+
  guides(fill=guide_legend(title="10 Years \n GDP per capita \n growth rate"))+
  theme_bw()+
  coord_fixed()+
  scale_fill_gradientn(colours=c("red","white","blue"), 
                       na.value ='lightgray',
                       values=scales::rescale(c(-80,0,180)))+
  labs(title='GDP per capita growth rate \n from 2011 to 2021')+
  theme_tufte(ticks = FALSE) + 
  theme(axis.line=element_blank(),
            axis.text.x=element_blank(),
              axis.text.y=element_blank(),
              axis.ticks=element_blank(),
              axis.title.x=element_blank(),
              axis.title.y=element_blank(),
            panel.grid.major = element_blank(),
            panel.grid.minor = element_blank(),
            panel.border = element_blank(),
            panel.background = element_blank())
  • Displaying the map
  ggiraph(code=print(g),width = .8,
                                 width_svg = 5,
                                 height_svg = 5,
                                 tooltip_opacity = 0.7,
                                 hover_css = "{fill:orange;}")