Again a post about how to plot maps in R, but this time I’ll explain how to use leaflet. If you want to know more about plotting shapefiles in R, you can read my previous post. This posts focuses on leaflet plots, but at some point I’ll also use a shapefile and plot this on the leaflet map.
Couple of years ago I traveled through Australia for some months and I would love to go back! When thinking of I case for this post, I decided to choose Sydney. I’m going to show you:
- how you can plot a map with leaflet
- how you can use different types of maps
- how to control the zoom level
- how to plot (custom) markers
- how to plot polygons by using a shapefile
Show different types of maps
The leaflet library is very easy to use. With just a few lines of code you can get amazing results. The following code installs the library leaflet . Then I create an object called map which I’m going to work with throughout this tutorial. I add leaflet and tiles to the object to get our first map of the world.
install.packages("leaflet") library(leaflet) # Plot map of the world map <- leaflet() %>% addTiles() map
You can change the zoom level en position of the map with the setView() function. Use the longitude and latitude which you want to have in the center of the map. You can tell the zoom parameter how detailed the map should be. Now we have the map of the world, but I want to zoom in on Sydney.
# Zoom in on specific location map <- map %>% setView(151.2293, -33.84, zoom = 12) map
Now we see the map of Sydney with zoom level 12. The higher the number, the more details you’ll see on the map.
This is the standard map, but there are many other maps available. You can find other types of maps on this website. The maps are actually tiles, a collection of images. In the example below I use two other types of tiles.
# Change map type map %>% addProviderTiles(providers$Stamen.Watercolor) map %>% addProviderTiles(providers$Esri.WorldStreetMap)
Alright, so now we know how to use different types of maps which is great if you want to have specific information available, such as hiking trails or heights. But I’m going to stick to the default map.
Plot (default) markers and clusters
For everything you want to plot on the map, you’ll need coordinates. I want to add markers for popular attractions and highlights in Sydney. The dataframe highlights_sydney contains three columns. One with the highlights name, one with the longitude and one with the latitude. Now, we can tell the function addMarkers() to use this data by specifying data, lng, lat and popup. The label group can be added to give this layer a name. This is something we’ll use in the next step.
# Plot marker(s) on map highlights_sydney <- data.frame(highlight = c("Sydney Harbour Bridge", "Sydney Tower Eye", "Darling Harbour", "Sydney Opera House", "Circular Quay", "Paddy's Haymarket", "China Town", "Taronga Zoo"), lng = c(151.2102386, 151.206566, 151.198706, 151.2148, 151.2021077, 151.2035053, 151.2034301, 151.2331529), lat = c(-33.8523063, -33.870451, -33.87488, -33.8567844, -33.8617552, -33.8793335, -33.8790999, -33.8430217) ) map <- map %>% addMarkers(data = highlights_sydney, lng = ~lng, lat = ~lat, popup = ~highlight, group = "markers") map
Default markers are added to the map. By clicking on the marker, a popup appears with the name of the attraction. The markers look fine, but I always want to customize everything as much as possible! Since we gave this layer a name, we can easily remove the markers by using hideGroup() and tell the function which group to hide.
Another option is to group the markers. When the density of markers is high, a number appears on the map telling us how many markers there are in that area. By double-clicking or zooming in the markers will appear. Grouped markers are extremely useful when there are a lot of markers and you want to keep a good overview. The map below shows how clustered markers are visualized on the map.
# Hide markers on map map <- map %>% hideGroup("markers") map # Cluster marker on map map %>% addMarkers(data = highlights_sydney, lng = ~lng, lat = ~lat, popup = ~highlight, clusterOptions = markerClusterOptions(), group = "custom marker clusters")
The more markers you have on the map, the more it will look like a heatmap. Well, we don’t have that many highlights to plot on the map so I’m not going to use the clusters. But I want to plot custom markers!
Add custom markers
It is possible to create your own image and use that as a marker instead of the blue one. But you can also keep the original one an change its colors and icon. That’s what I’ll do now.
There are different types of icons you can use. It is possible to use the icons from Font Awesome, Ionicons and Glyphicons. These are libraries containing thousands of icons. I add two columns to the highlights_sydney dataframe, one column with the icon name and another column with the icon library. For Font Awesome you can use ‘fa’, for Ionison ‘ion’ and for Glyphicon ‘glyphicon’. I use all three of them to show you how it works, but often I just use one of the libraries and get all my icons from it. Next, I create an object called icons which includes the information we need to create custom markers. I tell the icon and library to use the columns I just created. You can also change the color of the icon and the color of the marker. In this example I use the same color for each marker, but you can also use different colors for each marker. After defining the icons, I use addAwesomeMarkers() to plot the markers on the map.
# Add custom markers highlights_sydney$icon <- c("camera", "camera", "ship", "camera", "ship", "shopping-cart", "shopping-cart", "ios-paw") highlights_sydney$library <- c("glyphicon", "glyphicon", "fa", "glyphicon", "fa", "fa", "fa", "ion") icons <- awesomeIcons( icon = highlights_sydney$icon, library = highlights_sydney$library, iconColor = "#ffffff", markerColor = "blue" ) map <- map %>% addAwesomeMarkers(data = highlights_sydney, lng = ~lng, lat = ~lat, popup = ~highlight, icon = icons, group = "custom marker") map
Now we have a map of Sydney with pictograms belonging to each highlight in the city!
Add polygons to leaflet
I’ll end this tutorial by adding polygons to the leaflet map. So far I’ve added markers for the highlights in Sydney, but there are also some areas which are worth to visit. I want to color the area of Bondi beach, Manly and The Rocks. I could add a marker for these areas, but in fact it is not one point on the map but a much bigger surface. It is possible to do this by adding polygons to the map.
You can add polygons to a map when you have all the coordinates of the boundaries. I could explore the boundaries and register all of them, but takes to much time… Luckily the boundaries of the suburbs of Sydney are already collected in a shapefile which you can find here. You can read more about how to use shapefiles in R in this article. First we need to download the file and unpack the zip-file which includes the shapefile. In order to read the shapefile in R, I’ll use the maptools package and use readShapeSpatial() to read the shapefile. The shapefile includes all suburbs in Sydney, but I only want to show three of them. On this website I looked for the ID’s of Bondi beach, Manly and The Rocks. I only select these three suburbs from the shapefile by using the function subset() .
Adding polygons to a leaflet map can be done by using addPolygons() . You can add several parameters, such as the fill color and the opacity of the polygon, the color of the border and the text to be displayed in the popup. It is also possible to tell what the polygon should look like when there is a hover event. In that case, I wan to lower the opacity.
file = "C:/.../nswlocalitypolygonshp/NSW_LOCALITY_POLYGON_shp/NSW_LOCALITY_POLYGON_shp.shp" library(maptools) shapefile <- readShapeSpatial(file) shapefile_subset <- subset(shapefile, shapefile@data$LC_PLY_PID == 18012 | shapefile@data$LC_PLY_PID == 28239 | shapefile@data$LC_PLY_PID == 23813) map <- map %>% addPolygons(data = shapefile_subset, fillColor = "green", fillOpacity = 0.5, color = "black", weight = 2, popup = shapefile_subset@data$NSW_LOCA_2, highlightOptions = highlightOptions(fillOpacity = 0.3)) map
The final result looks like the map above. Hope this tutorial was helpful to you!