Requires leaflegend >= 1.0.0
The leaflet
package in R has built-in functionality for creating colorencoded geometries and annotating with color legends. Support is lacking in thearea of providing the ability to encode data with sizes or symbology except forthe case of circle markers. Size and symbology are an important part ofdata visualization on a map. Using the leaflegend
package, you can add bothto your leaflet maps without adding external css or javascript.
To create the appropriately sized symbols, The makeSymbolsSize
function cancreate a list of icons based on the output of sizeNumeric
. The baseSizeargument sets the center point size of the data scale to the mean of the valuese.g. with values 1, 2, 3, 4, 5 and a base size of 10, the resultant size inpixels of the symbols are 3.33, 6.67, 10, 13.33, 16.67. The symbols can beadded as icons to the map since they are svg elements. Some transparency isadded here to show overlapping symbols.
To add a legend for the sizes, addLegendSize
takes in the same values and usesthe pretty
function and breaks argument to create the scale. There may be someinconsistency between the number of breaks specified (leaflet
internals alsomake use of the pretty
function). It is easy to customize other aspects of thelegend for appearance such as here: the color, symbol, and transparency arematched to the symbols and we align the legend items horizontally.
library(leaflet)library(leaflegend)data("quakes")symbols <- makeSymbolsSize( values = quakes$depth, shape = 'diamond', color = 'red', fillColor = 'red', opacity = .5, baseSize = 10)leaflet() %>% addTiles() %>% addMarkers(data = quakes, icon = symbols, lat = ~lat, lng = ~long) %>% addLegendSize( values = quakes$depth, color = 'red', fillColor = 'red', opacity = .5, title = 'Depth', shape = 'diamond', orientation = 'horizontal', breaks = 5)
A helper function addSymbolsSize
simplifies the above code and one can usea palette to generate colors. The symbols are switched to a plus sign toprovide a smaller impact of area for overlapping points. The result is calleddouble-encoding and is a way to emphasize differences in data. Becausethe Richter scale is on a logarithmic scale, the actual readingof magnitude was taken as ten to the power of.
numPal <- colorNumeric('viridis', 10^(quakes$mag))leaflet(quakes) %>% addTiles() %>% addSymbolsSize(values = ~10^(mag), lat = ~lat, lng = ~long, shape = 'plus', color = ~numPal(10^(mag)), fillColor = ~numPal(10^(mag)), opacity = .5, baseSize = 1) %>% addLegendSize( values = ~10^(mag), pal = numPal, title = 'Magnitude', baseSize = 1, shape = 'plus', orientation = 'horizontal', opacity = .5, fillOpacity = .3, position = 'bottomleft', breaks = 5)
It is also possible to color encode and size encode with different values.Using a palette function from the leaflet package, thecolor/fillColor arguments can be used to base the color encoding on a differentvector of data than the values argument which is for size.
numPal <- colorNumeric('viridis', quakes$mag)leaflet(quakes) %>% addTiles() %>% addSymbolsSize(values = ~depth, lat = ~lat, lng = ~long, shape = 'plus', color = 'black', fillColor = ~numPal(mag), opacity = .5, baseSize = 10) %>% addLegendSize( values = quakes$depth, color = 'black', title = 'Depth', shape = 'plus', orientation = 'horizontal', opacity = .5, fillOpacity = 0, breaks = 5, position = 'bottomright') %>% addLegendNumeric( pal = numPal, title = 'Magnitude', shape = 'stadium', values = quakes$mag, fillOpacity = .5, decreasing = TRUE, position = 'bottomright')
Specifying color and fillColor will override any palette function that isprovided. Below are examples of all the different configurations for thelegend. The symbols are also available for makeSizeIcons
to matchthe desired legend.
numPal <- colorNumeric('viridis', quakes$depth)leaflet() %>% addTiles() %>% addLegendSize( values = quakes$mag, color = 'black', title = 'Magnitude', labelStyle = 'margin: auto;', shape = 'cross', orientation = 'horizontal', opacity = .7, numberFormat = function(x) { prettyNum(x, big.mark = ",", scientific = FALSE, digits = 3)}, breaks = 5, position = 'topright') %>% addLegendSize( values = quakes$mag, color = 'black', fillColor = 'transparent', title = 'Magnitude', labelStyle = 'margin: auto;', shape = 'cross', orientation = 'horizontal', opacity = .7, numberFormat = function(x) { prettyNum(x, big.mark = ",", scientific = FALSE, digits = 3)}, breaks = 5, position = 'topright') %>% addLegendSize( values = quakes$depth, pal = numPal, title = 'Depth', labelStyle = 'margin: auto;', shape = c('cross'), orientation ='horizontal', opacity = .7, color = 'black', breaks = 5, position = 'topright') %>% addLegendSize( values = quakes$depth, pal = numPal, title = 'Depth', labelStyle = 'margin: auto;', shape = c('cross'), orientation ='horizontal', opacity = .7, fillColor = 'black', breaks = 5, position = 'topright') %>% addLegendSize( values = quakes$depth, pal = numPal, title = 'Depth', labelStyle = 'margin: auto;', shape = c('cross'), orientation ='horizontal', opacity = .7, breaks = 5, position = 'topright')