A smooth transition between chloropleth and cartogram

This post describes how to make a smooth transition GIF between a chloropleth map and a cartogram. It starts by doing a basic map of Africa and then distorts country size using the cartogram library. Ggplot2 is then used to make a nice chloropleth version. Finally the tweenr and the gganimate libraries build a smooth transition between both maps. At the end of this post, you should obtain a .gif file that looks like this:

Before starting, we need a few libraries:

 

A basic map of Africa


 

 

The maptools library provides all the information we need to draw a map of Africa. All the country boundaries are stored in the ‘world_simpl’ object. Let’s load this object, keep only Africa, and draw a basic representation.

We only need 3 lines of code to start!

 

 

Compute cartogram boundaries


 

The afr object is a spatial object. Thus it has a ‘data slot’ that gives a few information concerning each region. You can visualise this info typing afr@data in our case. You will see that a column called POP2005 is present, providing the number of inhabitants per country in 2005.

Using this information we can use the cartogram library to build… a cartogram! Basically, it will distort the shape of every country proportionally to its number of inhabitants. The output is a new geospatial object that we can map like we’ve done before.

As you can see in the image on the left, Nigeria appears way bigger on this map, since it has a population of about 141M inhabitants!

 

A nicer representation using ggplot2


Let’s improve the appearance of these 2 maps using the ggplot2 library. Note that ggplot2 uses data frame and not geospatial object. The transformation to a data frame is done using the tidy function of the broom library. Since it does not transfer the data slot automatically, we merge it afterward.

The geom_polygon function is used to draw map data. See the graph #327 of the gallery for more explanation on chloropleth maps with ggplot2.

 

Compute several intermediate maps


The goal being to make a smooth animation between the 2 maps, we need to create a multitude of intermediate maps using interpolation. This is possible thanks to the awesome tweenr library. (See a few examples in the animation section of the gallery).

At the end we’ve got a big data frame which contains enough information to draw 30 maps. Three of these maps are presented above.

 

Make the animation with gganimate


The last step consists at building the 30 maps and compile them in a .gif file. This is done using the gganimate library. This library uses another aesthetic: frame. A new plot is made for each frame, that allows us to build the gif afterwards.

Done! You should have the gif in your working directory.

 

Conclusion


This post uses several concepts that are extensively described in the R graph gallery:

  • The chloropleth map section gives several examples of chloropleth maps, using different input types and several tools
  • The cartogram section gives further explanation about cartograms
  • The animation section explains more deeply how tweenR and gganimate work
  • The map section is a good starting point if you are lost in the map related packages jungle

If you are interested in dataviz, feel free to visit the gallery, or to follow me on twitter!

 

 

6 thoughts on “A smooth transition between chloropleth and cartogram

  1. Hi Yan, this looks great. Unfortunately this fails for me at:


    > data$time Error in
    $<-.data.frame(*tmp*, time, value = c(1L, 1L, 1L, 1L, 1L, : replacement has 5505 rows, data has 10467

    I'm not quite sure what you're doing in the data$time step for tweenr/gganimate, so I don't really know how to fix it.

  2. Hi Yan – great tutorial. I’m going to play around with this and try it with other geographies. I had a problem with the final line of your code – I think it needs to be “gg_animate” rather than “gganimate”. Or at least when I changed that it worked.

    Thanks for posting this.

Leave a Reply

Your email address will not be published.