I am working with the R programming language.
Using this built-in map of North Carolina, I generated 3 random variables (income, number of kids, weight) and then created maps (with the "leaflet" library) for this data (via a loop):
library(sf)
library(mapview)
library(leaflet)
library(leafgl)
library(colourvalues)
library(leaflet.extras)
library(magick)
nc <- st_read(system.file("gpkg/nc.gpkg", package="sf"), quiet = TRUE) %>%
st_transform(st_crs(4326)) %>%
st_cast('POLYGON')
set.seed(123)
nc$median_income <- sample(20000:100000, nrow(nc), replace = TRUE)
pal <- colorNumeric(palette = "YlOrRd", domain = nc$median_income)
nc$median_number_of_kids <- sample(0:5, nrow(nc), replace = TRUE)
pal2 <- colorNumeric(palette = "Blues", domain = nc$median_number_of_kids)
nc$median_weight <- rnorm(nrow(nc), mean = 175, sd = 15)
pal3 <- colorNumeric(palette = "Greens", domain = nc$median_weight)
vars <- list(median_income = pal, median_number_of_kids = pal2, median_weight = pal3)
maps <- list()
for (i in seq_along(vars)) {
var <- names(vars)[i]
pal <- vars[[i]]
map <- leaflet(data = nc) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addPolygons(fillColor = ~pal(get(var)),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME) %>%
addLegend(pal = pal,
values = ~get(var),
title = paste("Median", var),
position = "bottomright")
maps[[i]] <- map
}
map_1 <- maps[[1]]
map_2 <- maps[[2]]
map_3 <- maps[[3]]
mapshot(map_1, file = "map_1.png")
mapshot(map_2,file = "map_2.png")
mapshot(map_3, file = "map_3.png")
img1 <- image_read("map_1.png")
img2 <- image_read("map_2.png")
img3 <- image_read("map_3.png")
combined_img <- image_append(c(img1, img2, img3))
print(combined_img)
image_write(combined_img, path = "combined_maps.png", format = "png")
Here is how these maps look like (notice the legends):
I would now like to merge all these maps into a single file which allows the user to "toggle" between the different maps - I know how to do this with the following code:
combined_map = leaflet(data = nc) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addPolygons(fillColor = ~pal(median_income),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Income") %>%
addPolygons(fillColor = ~pal2(median_number_of_kids),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Number of Kids") %>%
addPolygons(fillColor = ~pal3(median_weight),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Weight (lbs)") %>%
addLayersControl(overlayGroups = c("Median Income", "Median Number of Kids", "Median Weight (lbs)"),
options = layersControlOptions(collapsed = FALSE))
My Problem: The code seems to have run, but the legends have disappeared!
My Question: I tried to learn more about why the legends are disappearing and what I can do to fix this problem - and I learned that it is possible to combine the "leaflet" library with javascript/html functions to modify the displays of the map (e.g. htmlwidgets::onRender("")
). Perhaps this could be a strategy to fix the problem of the disappearing legends?
Or have I overcomplicated everything and there is an easier way to do this?
Thanks!
EDIT 1: I found a similar post Add different legends in different layers on leaflet map in R and have been trying to adapt the code from the answer provided to my problem - perhaps this can also solve the problem?
combined_map = leaflet(data = nc) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addPolygons(fillColor = ~pal(median_income),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Income") %>%
addPolygons(fillColor = ~pal2(median_number_of_kids),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Number of Kids") %>%
addPolygons(fillColor = ~pal3(median_weight),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Weight (lbs)") %>%
addLegend(pal = pal, values = ~median_income, title = "Median Income", position = "bottomright", group="Median Income") %>%
addLegend(pal = pal2, values = ~median_number_of_kids, title = "Median Number of Kids", position = "bottomright", group="Median Number of Kids") %>%
addLegend(pal = pal3, values = ~median_weight, title = "Median Weight (lbs)", position = "bottomright", group="Median Weight (lbs)") %>%
addLayersControl(overlayGroups = c("Median Income", "Median Number of Kids", "Median Weight (lbs)"),
options = layersControlOptions(collapsed = FALSE))
EDIT 2: Based on the suggestions in the comments provided by @Alistaire, I tried to modify the code:
combined_map = leaflet(data = nc) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addPolygons(fillColor = ~pal(median_income),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Income") %>%
addPolygons(fillColor = ~pal2(median_number_of_kids),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Number of Kids") %>%
addPolygons(fillColor = ~pal3(median_weight),
fillOpacity = 0.8,
weight = 1,
color = "white",
popup = ~NAME,
label = ~NAME,
group = "Median Weight (lbs)") %>%
addLegend(pal = pal, values = ~median_income, title = "Median Income", position = "bottomright", group="Median Income") %>%
addLegend(pal = pal2, values = ~median_number_of_kids, title = "Median Number of Kids", position = "bottomright", group="Median Number of Kids") %>%
addLegend(pal = pal3, values = ~median_weight, title = "Median Weight (lbs)", position = "bottomright", group="Median Weight (lbs)") %>%
addLayersControl(baseGroups = c("Median Income", "Median Number of Kids", "Median Weight (lbs)"),
options = layersControlOptions(collapsed = FALSE))