How to add multiple lines label on a Leaflet map
Welcome
I have been teaching the Forecasting and Forensic Analytics course using R programming at Singapore Management University. One of the assignments is to draw a geographic map for data visualization purpose using the package:leaflet
. Students are asked to show a single-line text label
and a milti-line text popup
for markers on a map. Then one student asked how to show multi-line text label
as he found the syntax for label
and popup
is different. So this post is a record for future reference.
Leaftlet map with single line label
Let’s first load the data we will use to draw the map.
mapdata <- read.csv("mapdata.csv")
str(mapdata)
## 'data.frame': 7 obs. of 8 variables:
## $ conm : chr "ROBINSON & CO LTD" "METRO HOLDINGS LTD" "ISETAN (SINGAPORE) LTD" "CK TANG LTD" ...
## $ BUILDING : chr "RAFFLES CITY SHOPPING CENTRE" "NGEE ANN CITY" "ISETAN OFFICE BUILDING" "NIL" ...
## $ LATITUDE : num 1.29 1.3 1.29 1.28 1.37 ...
## $ LONGITUDE : num 104 104 104 104 104 ...
## $ start : int 2003 2003 2004 2006 2003 2010 2010
## $ end : int 2008 2018 2018 2009 2008 2018 2018
## $ highest_rev: num 142.6 73.9 110.5 68.8 99.2 ...
## $ lowest_rev : num 73.6 28.3 32.5 43.1 45.4 ...
As you can see from the above data frame structure, there are seven observations which represent seven retail companies in Singapore (conm
). It also contains their location, including building names (BUILDING
) and geographic locations (LATITUDE
and LONGITUDE
). It also includes their range of revenue (highest_rev
and lowest_rev
) in a specific period (from start
year to end
year).
The task is to show the seven companies on a Leaflet map, showing a label with company name and a popup with all other detailed information. Here is the code and map.
library(leaflet)
leaflet() %>%
addTiles() %>%
setView(lng = 103.85, lat = 1.3, zoom = 11) %>%
addMarkers(data = mapdata,
lng = ~LONGITUDE,
lat = ~LATITUDE,
label = ~conm,
popup = ~paste(conm, "<br>Building:", BUILDING,
"<br>Years active:", start, "to", end,
"<br>Revenue ($M) from", lowest_rev,
"to", highest_rev))
You might have noticed the difference between label
and popup
. A label will show up when you mouse over the marker, which is the default setting using the Leaflet. If you want to show the label directly, you need to add an option which will be shown later.
A popup will only show up when you click the marker on the map. Popup can display multiple lines easily as shown above. It can also recognize HTML tags such as <br>
which will insert a line break and <strong></strong>
which will bold the text in between.
However, the same syntax does not work on the label
argument.
leaflet() %>%
addTiles() %>%
setView(lng = 103.85, lat = 1.3, zoom = 11) %>%
addMarkers(data = mapdata,
lng = ~LONGITUDE,
lat = ~LATITUDE,
label = ~paste(conm, "<br>Building:", BUILDING),
popup = ~paste(conm, "<br>Building:", BUILDING,
"<br>Years active:", start, "to", end,
"<br>Revenue ($M) from", lowest_rev,
"to", highest_rev))
As shown above, the label does not show multiple lines properly. It seems the underline engines for label
and popup
are different. According to this post, the reason is that the developers do not add additional security check on popups.
So how to show multiple lines as label? We find the solution in the Leaflet
manual. You need to install a new package called package:htmltools
. You have to force it to recognize HTML tags using the HTML()
function.
labels <- paste(
"<strong>", mapdata$conm,
"</strong><br>Building:", mapdata$BUILDING) %>%
lapply(htmltools::HTML)
Alternatively, you may also use the sprintf()
function from Base R which returns a character vector containing a formatted combination of text and variable values. I think this is better than the paste
function.
labels <- sprintf(
"<strong>%s</strong><br/>Building: %s",
mapdata$conm, mapdata$BUILDING) %>%
lapply(htmltools::HTML)
Now we can plot the map and it will show labels with multiple lines text.
leaflet() %>%
addTiles() %>%
setView(lng = 103.85, lat = 1.3, zoom = 11) %>%
addMarkers(data = mapdata,
lng = ~LONGITUDE,
lat = ~LATITUDE,
label = ~labels,
popup = ~paste(conm, "<br>Building:", BUILDING,
"<br>Years active:", start, "to", end,
"<br>Revenue ($M) from", lowest_rev,
"to", highest_rev))
Do you want to show the label text directly even if you don’t mouse over? Just add an label option of noHide = TRUE
.
leaflet() %>%
addTiles() %>%
setView(lng = 103.85, lat = 1.3, zoom = 11) %>%
addMarkers(data = mapdata,
lng = ~LONGITUDE,
lat = ~LATITUDE,
label = ~conm,
labelOptions = labelOptions(noHide = TRUE),
popup = ~paste(conm, "<br>Building:", BUILDING,
"<br>Years active:", start, "to", end,
"<br>Revenue ($M) from", lowest_rev,
"to", highest_rev))
Conclusion
This document shows how to draw a map with multiple lines of label using the Leaflet package. This is a reference reading for the Forecasting and Forensic Analytics course at the Singapore Management University. I hope you will find this document useful.
You want to know more? Make an appointment with me at calendly.