I’ve been working on a chapter of a book looking at weather and production data for a major crop across the globe. One of the things I need to produce is a bubble map showing the relative production for each producing country worldwide, and region specific maps for each of the major production growing region.
There is a great package for doing this called rworldmap
. In this little post I present the code I used to produce figures for the book using rworldmap
.
Getting the data
First thing first, I need some data. The UN FAO very helpfully make these data available online, but it also turns out that there is an API and an R package to access that API called FAOSTAT.
The FAOSTAT package
The FAOSTAT package has a really simple interface that allows you to navigate through the available statistics, and download what you want. For example, I’m interested in the production and yield statistics for apple production within every apple producing region in the world
A slightly easier way of dealing with the information that comes back from the query is as follows:
Note that the useCHMT
option will clean up the data somewhat, as FAO data can double count territories like China, because of Taiwan, and Hong Kong. This check can also be conducted manually outside of the getFAO
function.
The FAOSTAT
package includes a function translateCountryCode()
which allows the UN numeric country code to be translated to an ISO2 or ISO3 letter code. In the current instance this is not a problem, because rworldwap
will take numeric UN codes.
The rworldmap package
Next step is to tidy up the FAOSTAT data before it can joined to a country map in rworldmap
. Initially, I am only interested in the most up-to-date production, so I’ll filter these out.
Now try to join this data to a map.
So there is a problem here; 68 of the codes in the apple2013
data failed to match up with data on the map. I’ll try to plot it anyway, and see what happens.
There’s definitely something funny going on here, because Antarctica is not known for its apple growing regions. Evidently there is more of a problem than was suggested in the mis-match warning.
I’ll try to solve this by converting the UN codes to ISO3 codes, although as noted in the FAOSTAT vignette there are some problems which are not addressed by the ISO coding system, for instance the change of names or lack of recognition (at the UN) of certain countries.
Better, but REU - Reunion island has not been matched probably because it has an accent over the e. It’s not critical for this demonstration, so I will leave it unmatched
Bubble maps
Adjusting the previous code to produce a bubble map is pretty simple. However producing legends in rworldmap
does not yet allow much customisation. I found a hacky solution to get the look I wanted.
Firstly, I didn’t want the numbers in the legend to appear as exponents, so I set options("scipen" = 10)
to allow these numbers to be displayed in full.
The next problem I ran into was that in the current version of rworldmap
(1.3-1) I couldn’t find a way to synchronise the colour of the map bubbles with the legend bubbles, nor could I seem to get the legend bubbles to be filled. To get round this, I cheated a bit here, and downloaded, edited the file containing the mapBubbles function (mapBubbles.r
), and hardcoded the legend symbols to be "red"
and pch = 19
, to match the map itself. I also added an option to the legend
call in mapBubbles()
so that by default the colour of the border matches the border background. At present these changes are hardcoded as I need a quick fix, but if I get a chance I will make better implementations and submit them as pull requests to the github repo. For now, I unzipped the package to a folder, made my changes then called devtools::load_all()
to load the altered package (I would have re-packaged it, but ran int some errors which I did not have the patience to fix).
So after all that, this is what I get. A bit more complicated than using a point and click GIS for pretty similar results, and a bit of a quick fix. If I need to make more of these kinds of visualisation, there are some really beautiful ways of doing this with D3.js; this (or this) is probably how I would do it next time.