view raw Rmd
Beautiful maps in a beautiful world
Maps are used in a variety of fields to express data in an appealing and
interpretive way. Data can be expressed into simplified patterns, and
this data interpretation is generally lost if the data is only seen
through a spread sheet. Maps can add vital context by incorporating many
variables into an easy to read and applicable context. Maps are also
very important in the information world because they can quickly allow
the public to gain better insight so that they can stay informed. It’s
critical to have maps be effective, which means creating maps that can
be easily understood by a given audience. For instance, maps that need
to be understood by children would be very different from maps intended
to be shown to geographers.
Knowing what elements are required to enhance your data is key into
making effective maps. Basic elements of a map that should be considered
are polygon, points, lines, and text. Polygons, on a map, are closed
shapes such as country borders. Lines are considered to be linear shapes
that are not filled with any aspect, such as highways, streams, or
roads. Finally, points are used to specify specific positions, such as
city or landmark locations. With that in mind, one need to think about
what elements are required in the map to really make an impact, and
convey the information for the intended audience. Layout and formatting
are the second critical aspect to enhance data visually. The arrangement
of these map elements and how they will be drawn can be adjusted to make
a maximum impact.
A solution using R and its ecosystem of packages
Current solutions for creating maps usually involves GIS software, such
as ArcGIS, QGIS, eSpatial, etc., which allow to visually prepare a map,
in the same approach as one would prepare a poster or a document layout.
On the other hand, R, a free and open-source software development
environment (IDE) that is used for computing statistical data and
graphic in a programmable language, has developed advanced spatial
capabilities over the years, and can be used to draw maps
programmatically.
R is a powerful and flexible tool. R can be used from calculating data
sets to creating graphs and maps with the same data set. R is also free,
which makes it easily accessible to anyone. Some other advantages of
using R is that it has an interactive language, data structures,
graphics availability, a developed community, and the advantage of
adding more functionalities through an entire ecosystem of packages. R
is a scriptable language that allows the user to write out a code in
which it will execute the commands specified.
Using R to create maps brings these benefits to mapping. Elements of a
map can be added or removed with ease — R code can be tweaked to make
major enhancements with a stroke of a key. It is also easy to reproduce
the same maps for different data sets. It is important to be able to
script the elements of a map, so that it can be re-used and interpreted
by any user. In essence, comparing typical GIS software and R for
drawing maps is similar to comparing word processing software (e.g.
Microsoft Office or LibreOffice) and a programmatic typesetting system
such as LaTeX, in that typical GIS software implement a WYSIWIG approach
(“What You See Is What You Get”), while R implements a WYSIWYM approach
(“What You See Is What You Mean”).
The package ggplot2 implements the grammar of graphics in R, as a way
to create code that make sense to the user: The grammar of graphics is a
term used to breaks up graphs into semantic components, such as
geometries and layers. Practically speaking, it allows (and forces!) the
user to focus on graph elements at a higher level of abstraction, and
how the data must be structured to achieve the expected outcome. While
ggplot2 is becoming the de facto standard for R graphs, it does not
handle spatial data specifically. The current state-of-the-art of
spatial objects in R relies on Spatial classes defined in the package
sp, but the new package
sf has recently implemented
the “simple feature” standard, and is steadily taking over sp.
Recently, the package ggplot2 has allowed the use of simple features
from the package sf as layers in a graph1. The combination of
ggplot2 and sf therefore enables to programmatically create maps,
using the grammar of graphics, just as informative or visually appealing
as traditional GIS software.
Drawing beautiful maps programmatically with R, sf and ggplot2
This tutorial is the first part in a series of three:
General concepts illustrated with the world Map (this document)
Adding additional layers: an example with points and
polygons
Positioning and layout for complex maps
In this part, we will cover the fundamentals of mapping using ggplot2
associated to sf, and presents the basics elements and parameters we
can play with to prepare a map.
Getting started
Many R packages are available from CRAN,
the Comprehensive R Archive Network, which is the primary repository of
R packages. The full list of packages necessary for this series of
tutorials can be installed with:
install.packages(c(&quot;cowplot&quot;, &quot;googleway&quot;, &quot;ggplot2&quot;, &quot;ggrepel&quot;, &quot;ggspatial&quot;, &quot;libwgeom&quot;, &quot;sf&quot;, &quot;rworldmap&quot;, &quot;rworldxtra&quot;))
We start by loading the basic packages necessary for all maps, i.e.
ggplot2 and sf. We also suggest to use the classic dark-on-light
theme for ggplot2 (theme_bw), which is appropriate for maps:
library(&quot;ggplot2&quot;)
theme_set(theme_bw())
library(&quot;sf&quot;)
The package rworldmap provides a map of countries of the entire world;
a map with higher resolution is available in the package rworldxtra.
We use the function getMap to extract the world map (the resolution
can be set to &quot;low&quot;, if preferred):
library(&quot;rworldmap&quot;)
library(&quot;rworldxtra&quot;)
world ggplot(data = world) +
geom_sf(fill = &quot;antiquewhite1&quot;) +
geom_text(aes(LON, LAT, label = NAME), size = 4, hjust = &quot;left&quot;,
color = &quot;darkblue&quot;, fontface = &quot;bold&quot;, check_overlap = TRUE) +
annotate(geom = &quot;text&quot;, x = -90, y = 26, label = &quot;Gulf of Mexico&quot;, fontface = &quot;italic&quot;, color = &quot;grey22&quot;, size = 6) +
annotation_scale(location = &quot;bl&quot;, width_hint = 0.5) +
annotation_north_arrow(location = &quot;bl&quot;, which_north = &quot;true&quot;, pad_x = unit(0.75, &quot;in&quot;), pad_y = unit(0.5, &quot;in&quot;),
style = north_arrow_fancy_orienteering) +
coord_sf(xlim = c(-102.15, -74.12), ylim = c(7.65, 33.97), expand = FALSE) +
xlab(&quot;Longitude&quot;) + ylab(&quot;Latitude&quot;) +
ggtitle(&quot;Map of the Gulf of Mexico and the Caribbean Sea&quot;) +
theme(panel.grid.major = element_line(color = gray(.5),
linetype = &quot;dashed&quot;, size = 0.5),
panel.background = element_rect(fill = &quot;aliceblue&quot;))
Saving the map with ggsave
The final map now ready, it is very easy to save it using ggsave. This
function allows a graphic (typically the last plot displayed) to be
saved in a variety of formats, including the most common PNG (raster
bitmap) and PDF (vector graphics), with control over the size and
resolution of the outcome. For instance here, we save a PDF version of
the map, which keeps the best quality, and a PNG version of it for web
purposes:
ggsave(&quot;map.pdf&quot;)
ggsave(&quot;map_web.png&quot;, width = 6, height = 6, dpi = &quot;screen&quot;)
Note: Support of sf objects is available since version 3.0.0 of
ggplot2, recently released on CRAN. ↩