How to do a choropleth map with the leaflet library.
0 – Introduction
This page aims to describe how to realise an interactive chloropleth map with the leaflet library of R. Note that you can zoom and hover country to have more information.
First we need to to load the shape file of the world map to know the border position of every country. See graph #168 to have a complete description of this step. We can summarize this step with these 4 lines of code:
1 2 3 4 5 6 7 8 9 |
# Download .shp file on the web: download.file("http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip" , destfile="world_shape_file.zip") system("unzip world_shape_file.zip") # Read the file with the rgdal library in R library(rgdal) world_spdf=readOGR( dsn= getwd() , layer="TM_WORLD_BORDERS_SIMPL-0.3") |
The world_spdf object contains the coordinates of the countries borders. It also contains the population size in 2005. You can see it in the world_spdf@data dataframe. With these 2 information we can draw a first basic choropleth map.
1 2 3 4 5 6 7 8 9 |
# Look at the info provided with the geospatial object head(world_spdf@data) summary(world_spdf@data) # Modify these info world_spdf@data$POP2005[ which(world_spdf@data$POP2005 == 0)] = NA world_spdf@data$POP2005 = as.numeric(as.character(world_spdf@data$POP2005)) / 1000000 %>% round(2) |
1 – Default chloropleth
With these information we can draw a first basic chloropleth map. We first need to create a color palette, and then use addPolygons() to add the shape of all country, with a color representing the number of people in the country. The result is quite disappointing! Since China and India have extremely high population, all the variation between countries is absorbed.. We need to fix that.
1 2 3 4 5 6 7 8 9 10 11 |
# Create a color palette for the map: mypalette = colorNumeric( palette="viridis", domain=world_spdf@data$POP2005, na.color="transparent") mypalette(c(45,43)) # Basic chloropleth with leaflet? leaflet(world_spdf) %>% addTiles() %>% setView( lat=10, lng=0 , zoom=2) %>% addPolygons( fillColor = ~mypalette(POP2005), stroke=FALSE ) |
And here is the histogram of the population per country. It is a good practice to check this distribution when you make a chloropleth. It helps to understand how your color palette should be implemented.
2 – Change color scale
There are several ways to pass from a numerical variable to palette of color. Leaflet proposes 3 possibilities that are described below: Numerical, Bins and Quantiles.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Color by quantile m=leaflet(world_spdf)%>% addTiles() %>% setView( lat=10, lng=0 , zoom=2) %>% addPolygons( stroke = FALSE, fillOpacity = 0.5, smoothFactor = 0.5, color = ~colorQuantile("YlOrRd", POP2005)(POP2005) ) m # Numeric palette m=leaflet(world_spdf)%>% addTiles() %>% setView( lat=10, lng=0 , zoom=2) %>% addPolygons( stroke = FALSE, fillOpacity = 0.5, smoothFactor = 0.5, color = ~colorNumeric("YlOrRd", POP2005)(POP2005) ) m # Bin m=leaflet(world_spdf)%>% addTiles() %>% setView( lat=10, lng=0 , zoom=2) %>% addPolygons( stroke = FALSE, fillOpacity = 0.5, smoothFactor = 0.5, color = ~colorBin("YlOrRd", POP2005)(POP2005) ) m |
3 – Custom the chloropleth map
In order to get a quality chloropleth map, there are several improvements we need to apply:
- Add a legend
- Find a smart colorscale + use a nice color palette
- Add a tooltip. When you hover a specific region, a box appears with custom text. This is very handy to add additional information to your map.
And here is the result and the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Create a color palette with handmade bins. mybins=c(0,10,20,50,100,500,Inf) mypalette = colorBin( palette="YlOrBr", domain=world_spdf@data$POP2005, na.color="transparent", bins=mybins) # Prepar the text for the tooltip: mytext=paste("Country: ", world_spdf@data$NAME,"<br/>", "Area: ", world_spdf@data$AREA, "<br/>", "Population: ", round(world_spdf@data$POP2005, 2), sep="") %>% lapply(htmltools::HTML) # Final Map leaflet(world_spdf) %>% addTiles() %>% setView( lat=10, lng=0 , zoom=2) %>% addPolygons( fillColor = ~mypalette(POP2005), stroke=TRUE, fillOpacity = 0.9, color="white", weight=0.3, highlight = highlightOptions( weight = 5, color = ~colorNumeric("Blues", POP2005)(POP2005), dashArray = "", fillOpacity = 0.3, bringToFront = TRUE), label = mytext, labelOptions = labelOptions( style = list("font-weight" = "normal", padding = "3px 8px"), textsize = "13px", direction = "auto") ) %>% addLegend( pal=mypalette, values=~POP2005, opacity=0.9, title = "Population (M)", position = "bottomleft" ) |
Related
Leave a Reply
Be the First to Comment!