Astonishingly easy mapping with R and mapview
InfoWorld | Dec 20, 2021
One short line of code give you a full-featured interactive choropleth map – complete with rollover text and popup data – thanks to the mapview package. See how simple it is to explore geospatial data in R. Data files available in the associated InfoWorld article: https://www.infoworld.com/article/3644848/astonishingly-easy-mapping-in-r-with-mapview.html If after watching this brief introduction you want a longer, more in-depth tutorial, check out package creator Tim Appelhans presentation (around 2 hours & 30 minutes): Part 1: https://youtu.be/hUzVvGezwo8?t=69 Part 2: https://www.youtube.com/watch?v=d88cVmL99xI
Copyright © 2021 IDG Communications, Inc.
Similar
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!
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!
Popular
Featured videos from IDG.tv