Leaflet Legend for Custom Markers in R
Asked Answered
J

3

15

I have an R Shiny app that uses Leaflet to create an interactive map. On this map, a categorical variable is used to designate different kinds of points and is visualized using custom markers (different icons, depending on the factor level).

What I would like to do is add a legend to the plot, but have the legend show the various marker icons instead of solid colours. The legends tutorial does not cover this.

I have come across another SO answer that seems to solve this - but it was done in JavaScript and I'm not sure how to translate it/if it can be translated to work in R. Anyone know how to accomplish this?

A basic reproducible example:

library(leaflet)

# Sample Data
data(quakes)
quakes <- quakes[1:10,]

# Choose Icon:
leafIcons <- icons(
  iconUrl = ifelse(quakes$mag < 4.6,
                   "http://leafletjs.com/docs/images/leaf-green.png",
                   "http://leafletjs.com/docs/images/leaf-red.png"
  ),
  iconWidth = 38, iconHeight = 95,
  iconAnchorX = 22, iconAnchorY = 94)

# Produce Map:
leaflet(data = quakes) %>% addTiles() %>%
  addMarkers(~long, ~lat, icon = leafIcons)
Jaban answered 16/6, 2016 at 14:43 Comment(1)
If it works, the simplest way is probably just to source the JavaScript.Richma
J
13

While the use of icons is not currently implemented in addLegend(), Yihui suggested the use of addControl(), using raw html - which works perfectly!

library(leaflet)

# Sample Data
data(quakes)
quakes <- quakes[1:10,]

# Choose Icon:
leafIcons <- icons(
  iconUrl = ifelse(quakes$mag < 4.6,
                   "http://leafletjs.com/examples/custom-icons/leaf-green.png",
                   "http://leafletjs.com/examples/custom-icons/leaf-red.png"
  ),
  iconWidth = 38, iconHeight = 95,
  iconAnchorX = 22, iconAnchorY = 94)

html_legend <- "<img src='http://leafletjs.com/examples/custom-icons/leaf-green.png'>green<br/>
<img src='http://leafletjs.com/examples/custom-icons/leaf-red.png'>red"

# Produce Map:
leaflet(data = quakes) %>% addTiles() %>%
  addMarkers(~long, ~lat, icon = leafIcons) %>%
  addControl(html = html_legend, position = "bottomleft")

Links

Which produces:

Leaflet Map with Categorical Legend

Jaban answered 16/6, 2016 at 14:56 Comment(2)
Tried this and it works but the icons in the legend are really large. Is there a way to resize them in the html_legend code or addControl()?Interradial
Yes, the icon size is defined in the icons() call, in the above they are set to 38px wide and 95px tall.Jaban
P
9

Responding to the comment above: you can change the size of the icons in the legend, regardless of the initial size you define. All you have to do is add

style='width:(desired_width)px;height:(desired_height)px'; to the HTML portion.

Specifically, your code would like:

library(leaflet)

# Sample Data
data(quakes)
quakes <- quakes[1:10,]

# Choose Icon:
leafIcons <- icons(
iconUrl = ifelse(quakes$mag < 4.6,
               "http://leafletjs.com/docs/images/leaf-green.png",
               "http://leafletjs.com/docs/images/leaf-red.png"
  ),
  iconWidth = 38, iconHeight = 95,
  iconAnchorX = 22, iconAnchorY = 94)

html_legend <- "<img src='http://leafletjs.com/docs/images/leaf-green.png'
style='width:10px;height:10px;'>green<br/> 

<img src='http://leafletjs.com/docs/images/leaf-red.png'  
style='width:10px;height:10px;'>red"

# Produce Map:
leaflet(data = quakes) %>% addTiles() %>%
addMarkers(~long, ~lat, icon = leafIcons) %>%
addControl(html = html_legend, position = "bottomleft")
Plossl answered 25/8, 2016 at 10:35 Comment(0)
P
0

You don't need to go so far as the raw HTML implementation of addControl. You can still use addLegend.

The key is knowing how it's implemented under the hood. When you specify a color in addLegend, it becomes the value for the background parameter in the CSS applied to the legend. So, instead of declaring a color, just declare a url to the image you want in the legend:

leafletProxy() %>% 
addLegend( 
   'bottomleft' , 
   colors=c(
      "url('http://leafletjs.com/docs/images/leaf-green.png')",
      "url('http://leafletjs.com/docs/images/leaf-red.png')"
   ),
   labels=c('Green','Red') 
)
Pushup answered 31/1 at 16:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.