Using mapcan to create choropleth maps

Andrew McCormack



The mapcan() function returns a data frame with geographic data that can be used in ggplot2.


Visualizing spatial data in R often involves working with large, specialized shape files that require a fair amount of conversion and manipulation before they are ready for use in ggplot. mapcan has done most of the heavy lifting, providing flexible, ggplot-ready geographic data.


At the most basic level, mapcan() requires two arguments: boundaries and type.

By default, mapcan() will provide geographic data for the entire country. You may wish to either exclude the territories from your map or create a map of only one province:


Creating a choropleth map with provincial boundaries

mapcan() gives us a data frame with necessary components (longitude, latitude, order, hole, piece, and group) for use with geom_polygon() in the ggplot package. It also provides four different variables to describe the province that make it easy to merge this data with provincial data of your choice.

Basic ingredients for ggplot

To create a plot with data from mapcan(), the following aesthetic mappings are required: x = long (longitude), y = lat (latitude), group = group (this tells geom_polygon() how to group observations—in this case, provinces). Let’s initialize the plot:

This doesn’t tell us much. We need to add a geom to visualize the map.

Using geom_polygon to plot the coordinates

To visualize the geographic data with ggplot, use geom_polygon(). It is important to also specify coord_fixed()—this fixes the relationship between longitude (the x-axis) and latitude (the y-axis):

You will notice that the axis text has no substantive significance. You can remove it, along with the axis ticks and background grid using theme_mapcan function, a ggplot theme that is part of the mapcan package:

Though beautiful, this map is not very informative (unless you are unfamiliar with the shape of Canada). Let’s add some province-level data.

Incorporate province-level statistics

It is relatively straightforward to merge your own province-level statistics into the geographic data that mapcan() provides. To illustrate, we will work with the province_pop_annual data frame that is included in the mapcan package. This dataset provides annual provincial/territorial population estimates dating back to 1971. Let’s use the most recent population data, from 2017:

The next step is to attach these numbers to every point on the polygons of the provinces. To do this, we first create the required geographic with mapcan(), then we use inner_join() from the dplyr package to merge in the pop_2017 data:

To colour the provinces according to their population size, set the population variable as a fill aesthetic. Because population is a continuous variable (and because I don’t like the default colours), I will use scale_fill_viridis_c() colour scale to colour the map.

### Creating a choropleth map with federal riding boundaries

Incorporate riding-level statistics

Like with province-level statistics above, we can also merge our own riding-level statistics into the riding-level geographic data that mapcan() has produced. We will work with the federal_election_results data frame that is included in the mapcan package. This dataset provides federal election results for all elections dating back to 1997. We will use the results of 2015 federal election to colour the ridings in British Columbia.

Note: At the moment, mapcan() only provides geographic data for the electoral boundaries (2013 Representation Order) of the 2015 federal election.

Next, we merge the two data frames (i.e. the geographic data and the election results data):

To colour the ridings according the winning party of the 2015 election, set the party variable as a fill aesthetic:

The colours are not ideal. We can easily provide our own custom colours that correspond to the colours associated with the different parties with ggplot’s scale_fill_manual():