Hi, I’m Sharon Machlis at IDG, here with Episode 67 of Do More With R: Astonishingly
easy mapping with the mapview package. R has some excellent mapping options. There’s
the leaflet R package, which I use when I really want to customize my maps. There’s
tmap, which I like a lot for its nice balance between power and ease of use. And recently
I’ve also started using mapview.
Like the leaflet package, mapview uses the leaflet JavaScript library under the hood.
What makes mapview different is that it’s specifically designed to generate useful default
maps with very little code. I mean Very. Little. Code. One function, 2 arguments, done. That
makes it super easy to explore geospatial data. Plus it has a couple of cool syntax
tricks I’d like to share.
For this demo I’ll use a shapefile of US states and data about population changes by
state in the last 20 years. If you want to follow along, you can get links to the data
either in the associated InfoWorld article or the YouTube description for this video.
In this code I join my file with state borders with the population data. You can see the
structure with dplyr’s glimpse().
This single line of code is all I need to create an interactive map to explore my data,
colored by percent change between 2010 and 2020, the column I specified. Please notice
what’s not here. Notice that I didn’t have to specify in any way that these are
polygons, or that I wanted this colored by polygon. mapview() figured it out. The mapview()
function only needed the dataset as the first argument, and the z-col – the column I want
to use for the fill color – as my 2nd argument. That’s it.
If I hover my mouse over a state, I see the z-col value. If I click on a state, I get
all the data fields on that state. That’s obviously not what you want an end user to
see, but it’s great for exploring your data. That popup is customizable, which I’ll get
to in a bit. But for data exploration, you get all this built in without having to say
that you want rollovers and popups.
That Feature ID as the popup title comes from the data’s row names. If your data set doesn’t
have row names, you get the row number. If you add row names to your data set with base
R’s row.names() function, you’ll get a better table title. By the way, if your table
doesn’t look nicely formatted like this, try updating GDAL on your system. I updated
my rgdal package and it solved a table formatting problem.
If you look very carefully at the top left just above the map as I move my mouse around,
you can (hopefully) see some text showing the longitude and latitude of where my mouse
is, and also the leaflet map zoom level. Bottom left shows the map scale in kilometers and
miles. Also if you look carefully, you should see a button at the bottom right with the
name of my data set and column. If I move the map around or zoom in or out, clicking
that button brings me back to the map starting point.
Adding points to a map is just as easy as polygons. For points, I’ll import a CSV
file of state capitals with their longitude and latitude. If you want to use a points
file like this for GIS work, you need to turn it into an R spatial object. (This isn’t
only a mapview thing). The sf package’s st_as_sf() function does this for you, with
data as first argument, defining which columns have longitude and latitude in the second
argument, and a crs projection used by a lot of background map tiles as the third argument.
Now I can add my points layer to my polygon map with the plus sign and the same mapview()
function. Again, I don’t have to tell mapview these are points; it knows. In fact, it knows
from the sf object which columns to use for latitude & longitude. Actually, once I’ve
created a mapview object, I can just add another layer with the name of the sf variable; I
don’t even have to call the mapview() function a second time!
Sometimes, you don’t even need to call the mapview() function at all! The startWatching()
function will automatically map any sf object you add to or change in your
R session! I’ll need to show you inside RStudio.
If you want to customize the default colors and opacity, there are arguments for that.
Color for polygon boundary lines; col.regions for polygon fill colors; and alpha.regions
for opacity. Here’s an example where I use “Greens” palette from the RColorBrewer
package and set the opacity to 1 so it’s not transparent at all. The palette only has
9 discrete colors. Mapview complains a bit that I didn’t give it a ramped palette over
all my values, but it does the work itself. If you’re not familiar with the RColorBrewer
package, it has a number of very popular palettes for mapmaking. You can use a diverging palette
in your map, too. Here I’m using RcolorBrewer and its Red to Yellow to Green palette, but
you can use any available palettes, or make your own. You can rename a layer with the
layer.name argument if you want a more user-friendly name on the legend, the bottom right button,
and in the layers option.
Now to a couple of those tricks I mentioned at the beginning. Here I’m creating two
maps, one for the 2010 to 2020 population change and the other for 2000 to 2010. I’m
using my Greens palettes and giving them new names. You can place the maps side by side
and have them move in sync with the leafsync package and
the sync() function. Or, you can put 2 maps on the same layer and have a side-by-side
slider to compare the two. That is also super simple if you load the leaflet.extras2 package!
Just the variable with one map, the vertical line character (many of us know it as the
Unix pipe character, but don’t confuse it with R pipes), and the 2nd map variable. It
was this elegant & easy syntax that first drew me to mapview.
You might have noticed on one of the maps earlier that the map background was dark.
That happens automatically, when mapview determines there’s a lot of light areas on the map.
You can stop that by setting the mapview option basemaps.color.shuffle to be false. As you
might be guessing now, there are a lot of other ways to customize your maps, either
within the mapview() function or by setting global session options.
You can turn off legends, hover labels, and popups altogether by setting any of those
options to FALSE. You can also customize your map’s projection. It’s sometimes useful
to show Alaska and Hawaii as insets, instead of where they actually are geographically,
for a more compact map area. A few R packages generate a map like that, including albersusa.
The first 4 lines of code here join an albersusa map with some new data. But if you look at
my mapview map, it’s still using the default background tiles. I don’t want Alaska and
Hawaii over Mexico!
If I tell mapview to use my data’s native projection, it will turn off the background
tiles altogether and show a properly projected map. I can customize my bin breakpoints with
the at argument. Here I’m setting breaks using base R’s sequence function, going
from -4 to 20 by increments of 2. The map & legend follow suit.
You can customize your popups and hover text using the same techniques as with the leaflet
R package. I don’t have time to go into this in depth, but it’s explained in the
accompanying InfoWorld article. Or, pause the video and look at the code; it’s not
complicated. Using the custom popups and hover text is very easy with the popup and label
arguments.
Mapview isn’t a general purpose dataviz library; but it will actually also generate
a scatterplot of a data file with two continuous numeric variables.
One of the most important things you’ll probably want to customize is your color palette.
If you’ve got a favorite, instead of inputting it every time you draw a map, you can set
a vector.palette argument. Here I use base R’s colorRampPalette to create a real palette
function from the 9 colors in that RcolorBrewer Greens palette I liked. That creates a palette
function from those colors, since different maps will need a different number of colors.
Now when I create a map, it uses my default palette without me having to specify it. There
are a lot more default options you can set, check the mapviewOptions help file.
But a reminder that most of what I just covered is nice to know, not need to use. I don’t
want you leaving thinking this is a complicated package. Remember: You can do exploratory
analysis of geographic data with a single short line of code. For polygons for points
including visualizing points by their attributes, such as changing their size based on your
data.
If you want to find out even more about mapview, package creator Tim Applehans gave a workshop
last year and the videos are available on YouTube.
That’s it for this episode, thanks for watching! For more R tips, head to the Do More With
R page at bit-dot-l-y slash do more with R, all lowercase except for the R. You can also
find the Do More With R playlist on YouTube’s IDG Tech Talk channel where you can subscribe
so you never miss an episode. Hope to see you next time. Stay healthy and safe, everyone!