Astonishingly easy mapping in R with mapview
R has some fantastic mapping possibilities. There is the leaflet R offer, which I use when I want to do a lot of customization. There is tmap, which I like for its good equilibrium amongst ability and simplicity of use. And not long ago I’ve started also applying mapview.
mapview’s raison d’être is exploratory visualization — much more particularly, making useful default maps with incredibly very little code. As very little code as:
mapview(mydata, zcol = "mycolumn")
1 function, two arguments, carried out. That would make it exceptionally straightforward to investigate geospatial knowledge, or to generate a rapidly prototype. As well as mapview has a couple of cool syntax possibilities for viewing numerous maps.
mapview in action
For this demo I’ll use a shapefile of US states and knowledge about populace changes by state in the last twenty several years. If you want to observe alongside, obtain the knowledge zip file:
Point out and state money knowledge for use with InfoWorld’s mapview tutorial Sharon Machlis
As usual, first a very little bit of knowledge prep. The code below hundreds 4 packages, downloads a GIS file defining state polygon borders, then joins that with state populations in 2000, 2010, and 2020.
library(tigris)
library(mapview)
library(dplyr)
library(sf)
us_geo <- tigris::states(cb = TRUE, resolution = '20m')
pop_knowledge <- readr::read_csv("state_population_data.csv")
all_knowledge <- inner_join(us_geo, pop_data, by = c("GEOID" = "GEOID"))
With my knowledge ready, this single line of code is all I have to have to generate an interactive map to investigate my knowledge, coloured by percent change amongst 2010 and 2020:
mapview(all_knowledge, zcol = "PctChange10_twenty")
A screenshot of the default map is demonstrated below, including a pop-up table which appears if you click on on a state and hover text which appears if you hover/mouse more than a state.
Observe what is not in the code that generated this map. I didn’t have to specify in any way that I’m analyzing polygons or that I want a map coloured by polygon mapview()
selected defaults primarily based on the form of geospatial file. The code mapview(all_knowledge, zcol = "PctChange10_twenty")
is all you have to have to make an interactive choropleth map — including hover text and pop-ups.
The default pop-up involves every single subject in my knowledge, and it is in all probability not what I’d want an close person to see. Nonetheless, it is useful for discovering my knowledge. And the pop-up is customizable, which I’ll get to in a bit.
If your knowledge established doesn’t have row names, mapview()
makes use of the row variety for the pop-up table’s major row. You can add row names to your knowledge established with foundation R’s row.names()
function to get much more person-helpful table titles.
By the way, if your table doesn’t glance as properly formatted as the just one in this map, test updating GDAL on your program. I up to date the rgdal offer on my program and it solved a table formatting dilemma.
Far more mapview characteristics
If you glance incredibly meticulously at the major remaining of the map in the screenshot above, you really should see some text demonstrating the longitude and latitude of the place my mouse was at the time I captured the image, as nicely as the leaflet map zoom stage. The two of these change as you interact with the map.
This default map also involves scale in kilometers and miles at the base remaining. And, at the base ideal, there is a button with the title of the knowledge established and column. If you go the map all-around or zoom in or out, clicking that button delivers you back again to the map commencing place.
Visualize factors with mapview
Including factors to a map is just as straightforward as polygons. For factors, I’ll use a CSV file of state capitals with their longitude and latitude.
In the code below, I use the rio offer to study the CSV, but you could use a further option these as readr::study_csv()
. To use latitude and longitude knowledge for GIS function in R (not only for mapview), you then have to have to turn the knowledge frame into a spatial item. The sf package’s st_as_sf()
function does this.
capitals <- rio::import("us-state-capitals.csv")
capitals_geo <- st_as_sf(capitals, coords = c("longitude", "latitude"),
crs = 4326)
st_as_sf()
requirements as arguments the knowledge frame, a vector defining which columns have longitude and latitude data, and your preferred coordinate reference program, in this circumstance just one used by a lot of track record map tiles.
Once the knowledge is reworked, I can use it to insert a factors layer to my map with a further get in touch with to mapview()
:
mapview(all_knowledge, zcol="PctChange10_twenty") +
mapview(capitals_geo)
I didn’t have to tell mapview that capitals_geo
consists of factors, or which columns keep latitude and longitude knowledge. In point, the moment I generate my first mapview item, I can insert levels to the map without the need of calling mapview()
again I can just use the place object’s title:
mapview(all_knowledge, zcol = "PctChange10_twenty") + capitals_geo
The map now seems like this:
Invoke automatic visualizations
You can also talk to mapview to quickly visualize geospatial objects in your R session. The package’s startWatching()
function makes a map of any sf item you insert to or change in your R session soon after the function is invoked. You can see how it functions in the video embedded at the major of this article.
Customise R maps with mapview
There are mapview()
arguments to personalize map possibilities these as shade
for polygon boundary traces, col.regions
for polygon fill colours, and alpha.regions
for opacity.
You can rename a layer with the layer.title
argument if you want a much more person-helpful layer title. This appears on the legend, the base ideal button, and when opening the layer button towards the major remaining.
In this future code block, I change the polygon colours and opacity applying the “Greens” palette from the RColorBrewer offer and an opacity of one so the polygons are opaque. (Note you will have to have the RColorBrewer offer installed if you want to operate this code on your program.)
mapview(all_knowledge, zcol = "PctChange10_twenty",
col.regions = RColorBrewer::brewer.pal(nine, "Greens"),
alpha.regions = one)
The Greens palette has a maximum of 9 discrete colours. mapview complains if you really don't give it a palette with the variety of colours it requirements, as in the warning below, but it will do the interpolating function for you.
Warning concept:
Found much less distinctive colours (nine) than distinctive zcol values (41)!
Interpolating shade vector to match variety of zcol values.
You can use a diverging palette in your map, as well, these as the RdYlGn palette:
mapview(all_knowledge, zcol = "PctChange10_twenty",
col.regions = RColorBrewer::brewer.pal(eleven, "RdYlGn"), alpha.regions = one)
This map’s dim track record appeared quickly, due to the fact mapview identified the map incorporated a lot of gentle colours. You can turn off that basemap behavior with
Visualize two maps together
Now to a couple of these cool syntax possibilities I stated at the beginning. Below I’m making two maps, just one for the 2010 to 2020 populace change and the other for 2000 to 2010:
map2020 <- mapview(all_data, zcol = "PctChange10_20",
col.regions = RColorBrewer::brewer.pal(nine, "Greens"), alpha.regions = one,
layer.title = "Pct change 2010-2020"
)
map2010 <- mapview(all_data, zcol = "PctChange00_10",
col.regions = RColorBrewer::brewer.pal(nine, "Greens"), alpha.regions = one,
layer.title = "Pct change 2000-2010"
)
You can position the maps aspect by aspect and have them go in sync with the leafsync offer and the sync()
function.
library(leafsync) sync(map2010, map2020)
Or, you can put two maps on the same layer and have a aspect-by-aspect slider to review the two, many thanks to the leaflet.extras2 offer and the |
(Unix pipe, not R pipe) character.
map2010 | map2020
Really do not want legends, pop-ups, or hover text on a map? Those people can be turned off with
mapview(all_knowledge, zcol = "PctChange10_twenty", legend = Bogus, label = Bogus, popup = Bogus)
You can also turn off the track record map tiles by applying a knowledge set’s tailor made projection. 1 circumstance the place that is useful is if you want a map of the US demonstrating Alaska and Hawaii as insets, as a substitute of the place they really are geographically, for a much more compact display.
The first 4 traces of code below use the albersusa offer to make a GIS file with Alaska and Hawaii as insets. But the ensuing default mapview map of this knowledge however displays default track record tiles, ensuing in Alaska and Hawaii appearing overlayed onto Mexico.
library(albersusa)
us_geo50 <- usa_sf("lcc") %>% mutate(GEOID = as.character(fips_state))
pop_data50 <- readr::read_csv("data/state_population_data50.csv")
all_data50 <- inner_join(us_geo50, pop_data50, by = c("GEOID" = "GEOID"))
mapview(all_data50, zcol = "PctChange10_twenty")
If I tell mapview to use the data’s native projection, although, the projection is precise and the track record no more time involves map tiles.
mapview(all_data50, zcol = "PctChange10_twenty",
native.crs = Legitimate)
Far more R mapview customizations
You can personalize your bin breakpoints with the at
argument. In the code below, I established breaks applying foundation R’s seq()
function, likely from -four to twenty by increments of two. The map colours and legend will present the new breaks.
mapview(all_knowledge, zcol = "PctChange10_twenty",
at = seq(-four, twenty, two))
You can personalize your pop-ups and hover text applying the same strategies as with the leaflet R offer. I’m confident there are numerous techniques to do this, but this is my usual system:
Initial, generate a vector of character strings — with HTML code if you want formatting — applying the entire dataframe$column_title
syntax for variables. I uncover the glue offer useful for this, while you could paste()
as nicely. For instance:
mylabel <- glue::glue("all_data$State all_data$PctChange10_20%")
Second, implement the htmltools package’s HTML()
function to the vector with lapply()
so you close up with a record — due to the fact you have to have a record — these as:
mypopup <- glue::glue("all_knowledge$Point out
Modify 2000-2010: all_knowledge$PctChange00_10%
Modify 2010-2020: all_knowledge$PctChange10_twenty%") %>%
lapply(htmltools::HTML)
mylabel <- glue::glue("all_data$State all_data$PctChange10_20%") %>%
lapply(htmltools::HTML)
My pop-up record now seems a little something like this:
head(mypopup, 3)
[[one]] Washington
Modify 2000-2010: fourteen.one%
Modify 2010-2020: fourteen.six%
[[two]] Puerto Rico
Modify 2000-2010: -two.two%
Modify 2010-2020: -eleven.eight%
[[3]] South Dakota
Modify 2000-2010: 7.nine%
Modify 2010-2020: eight.nine%