R que R

Data visualization: Animated maps (ENG)

Wed, Mar 25, 2020
R maps
#maps #gganimate #ggplot2 #mapas


Libraries / packages


There are plenty of packages available in R designed to create interactive or animated plots, graphs and/or maps. This post is not intended to carry out an exhaustive analysis of all of them, but to present some examples of animated maps using {gganimate}. I hope that it may be of interest to someone. In a way this post can be considered as a continuation of two dashboards previously made, where it was shown how to make static choropleth maps (link to dashboard) and how to create static maps using geographic coordinates (link to post). At this point I will show three maps using {gganimate}, but I might add more examples using different packages in the future.



library(tidyverse)
library(gapminder)
library(echarts4r)
library(gganimate)
library(ggiraph)
library(widgetframe)
library(ggthemes)
library(plotly)
library(viridis)
library(DT)


Datasets


In this post we are going to use a well known dataset called gapminder / gapminder_unfiltered included in the package of the same name. If you have read previous post of this blog you might be familiarized with it as I have used the gapminder dataset a few times in other examples, even on the previously mentioned dashboards. The dataframe contains the following information for a list of countries (187 in the gapminder_unfiltered version):

  • country: Country names.
  • continent: Continent of each country.
  • year: The data range covers the period 1952-2007 (in 5-year increments).
  • lifeExp: Life expectancy of each country in years.
  • pop: Population.
  • gdpPercap: GDP per capita in inflation-adjusted dollars.

We will also use the meterorite landings dataset from the Tidytuesday project (11-06-2019). As the name indicates, this datasets is about meteorites and the information comes from the Meteoritical Society of NASA. Although the dataset includes more information, we will mainly be interested in the following variables:

  • name: Meteorite name
  • mass: Mass in grams
  • year: Year found
  • lat: Latitude
  • long: Longitude
  • fall: fall or found meteorite


gapminder dataset:



# country codes in gapminder::country_codes

gapminder_codes <- gapminder::country_codes

# countries with info in gapminder::gapminder_unfiltered

gapminder <-gapminder::gapminder_unfiltered

# We join both datasets with inner_join to get a dataset with the info by country, continent and country-code

gapminder <- gapminder %>%
  inner_join(gapminder_codes, by= "country") %>%
  mutate(code = iso_alpha)

# A map of the world (Antarctica removed)

world <- map_data("world") %>%
  filter(region != "Antarctica")


gapminder_data <- gapminder %>%
  inner_join(maps::iso3166 %>%
               select(a3, mapname), by= c(code = "a3")) %>%
  mutate(mapname = str_remove(mapname, "\\(.*"))



datatable(gapminder_data)

Meteorites dataset



meteoritos <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-06-11/meteorites.csv")

datatable(meteoritos)


Evolution in time with {gganimate}


{gganimate} is a extension of {ggplot2} for creating animated ggplots. This package includes a wide range of functions that can be added to our {ggplot2} object (maps also) to include animations. As the package {gganimate} allows animations, we can also use them to show the change of a variable over time. In the next paragraphs we will present three examples of animated maps using this package. However, there are many functionalities and options available that you can use to customize your own animations (link to more info).


Animated choropleth maps

In this ocassion we will select only four years (1992, 1997, 2002, 2007) and the {viridis} package.



mapa_animado_4 <- gapminder_data %>%
 filter(year %in% c(1992, 1997, 2002, 2007)) %>%
  right_join(world, by= c(mapname = "region")) %>%
  ggplot(aes(long, lat, 
             group= group, 
             fill= lifeExp)) +
  geom_polygon(color = "white", 
               size = 0.01) +
  theme_void() +
  scale_fill_viridis(option = "B",
                     name= "Years",
                     guide = guide_colorbar(
                       direction = "horizontal",
                       barheight = unit(2, units = "mm"),
                       barwidth = unit(100, units = "mm"),
                       draw.ulim = FALSE,
                       title.position = "top",
                       title.hjust = 0.5,
                       title.vjust = 0.5 )) +
  labs(title="Life Expectancy",
       subtitle = "{current_frame}",
       caption = "Source: gapminder.org")  +
  theme(
    plot.title = element_text(size = 12, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    plot.caption = element_text(size = 8, hjust = 1),
    legend.position = "bottom") +
  coord_fixed (ratio = 1.3) +
  transition_manual(year)


animate(mapa_animado_4, 
        fps = 10, 
        height = 500, 
        width = 700)


Animated maps using geographic coordinates

Meteorite falls, also called observed falls, are those meteorites collected after their fall from space was observed by automated devices or by people. In the dataset those meteorites are called fell and we will only work with those ones in our graphs. There are 1107 documented falls in our dataset although, as the Meteoritical Bulletin Database indicates, the number of confirmed falls has increased since then.


In the first example we want to indicate the locations of the meteorites falls on a map by year. The argument nframes indicates the number of frames to render (the default is 100), and fps makes reference to the framerate of the animation or frames per second (the default is 10).



options(scipen = 999) 

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



mapa_animado <- world %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey20",
               color = "white",
               size = 0.1) +
  geom_point(data= meteoritos_Mundo, 
             x = meteoritos_Mundo$long, 
             y = meteoritos_Mundo$lat,
             color = "orange",
             alpha = 0.7,
             size = 0.2) +
  transition_states(year,
                    transition_length = 1, 
                    state_length = 1) +
  shadow_mark(past = TRUE) +
  labs( title = "Meteorite Falls \n Year :{closest_state}",
        caption = "The Meteoritical Society") +
  theme_map() +
  theme(plot.title = element_text(size = 10, hjust = 0.5),
    plot.subtitle = element_text(size = 8, hjust = 0.5),
    plot.caption = element_text(size = 6, hjust = 1))


animate(mapa_animado, 
        fps = 15, 
        nframes = 350,
        height = 500, 
        width = 700, 
        res = 150)


In the next example we also want to show the locations of the meteorites falls on a map, but in this ocassion we will enter the enter and exit functions in order to modify the state of appearing and disappearing data. We will use the functions enter_fade() and exit_shrink() to modify the entrance and exit animations but you can even create you own animation using the enter_manual() and exit_manual() functions.



mapa_animado_3 <- world %>%
  ggplot() +
  geom_polygon(aes( x= long, y = lat, group = group),
               fill = "grey20",
               color = "white",
               size = 0.01) +
  geom_point(data= meteoritos_Mundo, 
             aes(x = long, 
                 y = lat, 
                 size = mass),
             color = "orange",
             alpha = 0.9) +
  transition_components(year) +
  enter_fade() +
  exit_shrink() +
  ease_aes("sine-in-out") +
  shadow_mark(past = FALSE) +
  labs( title = "Meteorite Landings \n Year :{round(frame_time)}",
        caption = "The Meteoritical Society") +
  theme_map() +
  scale_size_continuous(guide = F) +
  scale_color_discrete(name = "Type") +
  theme(plot.title = element_text(size = 10, hjust = 0.5))

animate(mapa_animado_3, 
        fps = 2, 
        height = 500, 
        width = 700, 
        res = 150)