I am trying to plot a map with multiple layers. However, when selecting the group I want to show in the controlLayer panel, it changes the map but not the legend. In fact, the 2 legends are always displayed together on the map, but I only want one of them at a time.
Here is the code I use :
leaflet(data) %>%
addProviderTiles("Esri.WorldStreetMap") %>%
addRasterImage(r, opacity = 1, colors = cb, group = "Predictions") %>%
addLegend(pal = cb, values = wind_speed_range, title = "Wind Speed", opacity = 1, group = "Predictions", position = "topright") %>%
addCircles(radius = ~ residual*7000, color = "black", fillColor = ~ cb(predictions), fillOpacity = 1, label = ~ paste(as.character(residual), " / ", as.character(vitesse_vent), " / ", as.character(predictions)), weight = 2, group = "Predictions") %>%
addRasterImage(raster_difference, opacity = 1, colors = cb_correction, group = "Corrections") %>%
addLegend(pal = cb_correction, values = correction_range, title = "Corrections", opacity = 1, group = "Corrections", position = "topright") %>%
addLayersControl(
baseGroups = c("Prédictions", "Corrections"),
options = layersControlOptions(collapsed = FALSE),
position = "topleft"
)
As you can see, I already tried the solution of this post. I also tried with overlayGroup instead of baseGroup, but the problem is still here.
The image below is what I get using this code :
You can clearly see the two legends.
Code
Unfortunately, you did not provide a reprex, so I show it with a made up example:
library(leaflet)
cities1 <- data.frame(City = factor(c("Boston", "Hartford",
"New York City", "Philadelphia", "Pittsburgh", "Providence")),
Lat = c(42.3601, 41.7627, 40.7127, 39.95, 40.4397, 41.8236),
Long = c(-71.0589, -72.6743, -74.0059, -75.1667, -79.9764, -71.4222),
Pop = c(645966L, 125017L, 8406000L, 1553000L, 305841L, 177994L),
Type = factor(c("C", "D", "A", "A", "B", "C")))
cities2 <- data.frame(City = factor(c("Baltimore", "Ithaca", "Wareham")),
Lat = c(39.299236, 42.443962, 41.761452),
Long = c(-76.609383, -76.501884, -70.719734),
Pop = c(609032L, 30569L, 22666L),
Type = factor(letters[1:3]))
pal1 <- colorFactor("viridis", domain = cities1$Type)
pal2 <- colorFactor("Set1", domain = cities2$Type)
leaflet(cities1) %>%
addTiles() %>%
addCircles(data = cities1, lng = ~Long, lat = ~Lat, weight = 1, group="one",
radius = ~sqrt(Pop) * 30, popup = ~City, color = ~pal1(Type), opacity = .9
) %>%
addLegend(pal = pal1, values = ~Type, group = "one", layerId = "one") %>%
addCircles(data = cities2, lng = ~Long, lat = ~Lat, weight = 1, group = "two",
radius = ~sqrt(Pop) * 30, popup = ~City, color = ~pal2(Type), opacity = .9
) %>%
addLegend(pal = pal2, values = ~Type, data = cities2, group = "two", layerId = "two") %>%
addLayersControl(
baseGroups = c("one", "two"),
options = layersControlOptions(collapsed = FALSE),
position = "topleft"
) %>%
htmlwidgets::onRender("
function() {
var map = this;
var legends = map.controls._controlsById;
function addActualLegend() {
var sel = $('.leaflet-control-layers-base').find('input[type=\"radio\"]:checked').siblings('span').text().trim();
$.each(map.controls._controlsById, (nm) => map.removeControl(map.controls.get(nm)));
map.addControl(legends[sel]);
}
$('.leaflet-control-layers-base').on('click', addActualLegend);
addActualLegend();
}")
Explanation
You can define some custom JavaScript which reacts upon the changes of the radio buttons. When they change, I basically delete all controls and add the selected. In order for this to work, I need to save a copy of the controls first. This is of course a bit hackish (especially since I am accessing the "private" _controlsById slot of the map), but from my quick scan of the leaflet API I did not find a better entry point.
Screenshot
Related
this is my first time working with R shiny and I am attempting to integrate shiny features with a leaflet map I have made. The idea is that I would like to have radio buttons which toggle between four different polygons layers generated by shapefile data, and a slider which controls the opacity of the polygon layer. I used code from several different tutorials on shiny and leaflet but when I attempt to generate the map I get the following warning:
Warning: Error in google_dispatch: Invalid map parameter
[No stack trace available]
the panel with my buttons and slider appear but not my map. I believe this issue is with this section of my code:
opacityf <- reactive({
opacity[opacity$value == input$slider, ]
})
layerf <- reactive({
switch(input$layer,
countiesr = counties,
regionsr = regions,
triber = tribe,
publicr = public,
selected = NULL)
})
observe({
leafletProxy(mapId = "Intensity_Map", data = layerf()) %>%
clear_polygons() %>%
addPolygons(fillOpacity = opacityf(),
weight = 1,
color = "purple4")
})
}
I created a data frame with values between 0.0 and 1.0 for the opacity slider and I am attempting to direct shiny to change to opacity value to be whatever the slider value is. For the buttons I am trying to direct shiny to plot one of the four spatial polygon objects I created using the shapefiles. I believe I have a mistake in here somewhere but I cannot seem to figure out what it is.
Here is the rest of my code for reference:
ui <- fluidPage(
titlePanel("Cyano-Toxin Concentration in Relation
to OEHHA Action Levels for Acute Toxicity in Dogs"),
sliderInput(inputId = "slider",
label = "Opacity",
min = 0,
max = 1,
value = NULL,
step = 0.1),
radioButtons(inputId = "layer",
label = "Map Layer",
choices = c("Counties" = "countiesr",
"Regional Boards" = "regionsr",
"Tribal Lands" = "triber",
"Public Lands" = "publicr")),
leafletOutput("Intensity_Map")
)
opacity <- data.frame(value = c(0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0))
server <- function(input, output, session){
output$Intensity_Map <- renderLeaflet({
leaflet() %>% setView(lat = 36.778259, lng = -119.417931, zoom = 5) %>% addTiles(group = "None") %>%
addCircleMarkers(
data = ws_ND,
radius = 4,
color = "grey",
stroke = FALSE, fillOpacity = 0.7,
label = ~as.character(label),
popup = ~as.character(popup),
group = "None Detected"
)%>%
addCircleMarkers(
data = ws_M,
radius = ws_M$Radius,
color = ~pala(Percent.of.AL),
stroke = FALSE, fillOpacity = 0.7,
label = ~as.character(label),
popup = ~as.character(popup),
group = "Microcystin/Nod."
)%>%
addCircleMarkers(
data = ws_C,
radius = ws_C$Radius,
color = ~palc(Percent.of.AL),
stroke = FALSE, fillOpacity = 0.7,
label = ~as.character(label),
popup = ~as.character(popup),
group = "Cylindrospermopsin"
)%>%
addCircleMarkers(
data = ws_A,
radius = ws_C$Radius,
color = ~palb(Percent.of.AL),
stroke = FALSE, fillOpacity = 0.7,
label = ~as.character(label),
popup = ~as.character(popup),
group = "Anatoxin-a"
)%>%
addCircleMarkers(
data = ws_S,
color = "yellow",
radius = 8,
stroke = FALSE, fillOpacity = 0.7,
label = ~as.character(label),
popup = ~as.character(popup),
group = "Saxitoxin"
)%>%
addLayersControl(
overlayGroups = c("None Detected", "Microcystin/Nod.","Cylindrospermopsin","Anatoxin-a","Saxitoxin"),
options = layersControlOptions(collapsed = FALSE),
position = "topright"
)%>%
addLegend("bottomright", pal = palab, values = (labels = c("1. < 25%","2. 25% - 49%","3. 50% - 99%", "4. ≥ 100%")),
title = "Microcystin/Nod.",
opacity = 1,
group = "Microcystin/Nod."
)%>%
addLegend("bottomright", pal = palbb, values = (labels = c("1. < 25%","2. 25% - 49%","3. 50% - 99%", "4. ≥ 100%")),
title = "Anatoxin-a",
opacity = 1,
group = "Anatoxin-a"
)%>%
addLegend("bottomright", pal = palcb, values = (labels = c("1. < 25%","2. 25% - 49%","3. 50% - 99%", "4. ≥ 100%")),
title = "Cylindrospermopsin",
opacity = 1,
group = "Cylindrospermopsin") })
opacityf <- reactive({
opacity[opacity$value == input$slider, ]
})
layerf <- reactive({
switch(input$layer,
countiesr = counties,
regionsr = regions,
triber = tribe,
publicr = public,
selected = NULL)
})
observe({
leafletProxy(mapId = "Intensity_Map", data = layerf()) %>%
clear_polygons() %>%
addPolygons(fillOpacity = opacityf(),
weight = 1,
color = "purple4")
})
}
shinyApp(ui, server)
Any thoughts would be greatly appreciated!
I'm building a leaflet map on R having multiple layers that are controlled by addLayersControl. Every layer as the same spatial information, so only the data associated to each polylines changes. The idea is to have a basic map, where the user decide which data field is display. I succeeded at making the map, however I noticed that the size of the html file produced is huge.
In my actual context, making the map with only one layer leads to a ~20mb file. However, if I add one field it gets to ~40mb and three layer ~60mb. So it seems to me that the html produced is loading the same shapefile 3 times instead of simply using one shapefile and linking it a data frame of some sort.
Am I stock with this behavior of leaflet or is there a way to file size inflation in my context? I may not have programmed my leaflet the better way...
I've made a reproducible example to show the problem. It uses a small shapefile so the size problem is not dramatic, however the point is the same, which is constantly doubling file size. Also, the example is lengthy, sorry about that, I could'n find a way to simplify it further.
Preparation:
# loading the libraries
library(sf)
library(leaflet)
library(htmlwidgets)
# preparing the shapefile
nc <- st_read(system.file("gpkg/nc.gpkg", package="sf"), quiet = TRUE) %>%
st_transform(st_crs(4326))
# preparing the colors (not really important)
pal.area <- colorNumeric(palette = "inferno", domain = range(nc$AREA))
pal.perim <- colorNumeric(palette = "inferno", domain = range(nc$PERIMETER))
pal.cnty <- colorNumeric(palette = "inferno", domain = range(nc$CNTY_))
pal.sid74 <- colorNumeric(palette = "inferno", domain = range(nc$SID74))
Making the leaflet, this section is long, however it's simply 4 leaflet maps created one after another by adding one layer at a time. It's mostly copy-pasted work:
###
one_layer <- leaflet(data = nc) %>%
addTiles() %>%
addPolylines(fillColor = ~pal.area(AREA),
fill = TRUE,
opacity = 0.8,
group = "area") %>%
addLegend("bottomright",
pal = pal.area, values = ~AREA,
opacity = 1, group = "area"
)
###
###
two_layers <- leaflet(data = nc) %>%
addTiles() %>%
addPolylines(fillColor = ~pal.area(AREA),
fill = TRUE,
opacity = 0.8,
group = "area") %>%
addLegend("bottomright",
pal = pal.area, values = ~AREA,
opacity = 1, group = "area") %>%
addPolylines(fillColor = ~pal.perim(PERIMETER),
fill = TRUE,
opacity = 0.8,
group = "perim") %>%
addLegend("bottomright",
pal = pal.perim, values = ~PERIMETER,
opacity = 1, group = "perim"
) %>%
addLayersControl(
overlayGroups = c("area", "perim"), position = "bottomleft",
options = layersControlOptions(collapsed = FALSE)
)
###
###
three_layers <- leaflet(data = nc) %>%
addTiles() %>%
addPolylines(fillColor = ~pal.area(AREA),
fill = TRUE,
opacity = 0.8,
group = "area") %>%
addLegend("bottomright",
pal = pal.area, values = ~AREA,
opacity = 1, group = "area") %>%
addPolylines(fillColor = ~pal.perim(PERIMETER),
fill = TRUE,
opacity = 0.8,
group = "perim") %>%
addLegend("bottomright",
pal = pal.perim, values = ~PERIMETER,
opacity = 1, group = "perim"
) %>%
addPolylines(fillColor = ~pal.cnty(CNTY_),
fill = TRUE,
opacity = 0.8,
group = "cnty") %>%
addLegend("bottomright",
pal = pal.cnty, values = ~CNTY_,
opacity = 1, group = "cnty"
) %>%
addLayersControl(
overlayGroups = c("area", "perim", "cnty"), position = "bottomleft",
options = layersControlOptions(collapsed = FALSE)
) %>%
hideGroup(c("perim","cnty"))
###
###
four_layers <- leaflet(data = nc) %>%
addTiles() %>%
addPolylines(fillColor = ~pal.area(AREA),
fill = TRUE,
opacity = 0.8,
group = "area") %>%
addLegend("bottomright",
pal = pal.area, values = ~AREA,
opacity = 1, group = "area") %>%
addPolylines(fillColor = ~pal.perim(PERIMETER),
fill = TRUE,
opacity = 0.8,
group = "perim") %>%
addLegend("bottomright",
pal = pal.perim, values = ~PERIMETER,
opacity = 1, group = "perim"
) %>%
addPolylines(fillColor = ~pal.cnty(CNTY_),
fill = TRUE,
opacity = 0.8,
group = "cnty") %>%
addLegend("bottomright",
pal = pal.cnty, values = ~CNTY_,
opacity = 1, group = "cnty"
) %>%
addPolylines(fillColor = ~pal.sid74(SID74),
fill = TRUE,
opacity = 0.8,
group = "sid74") %>%
addLegend("bottomright",
pal = pal.sid74, values = ~SID74,
opacity = 1, group = "sid74"
) %>%
addLayersControl(
overlayGroups = c("area", "perim", "cnty", "sid74"), position = "bottomleft",
options = layersControlOptions(collapsed = FALSE)
) %>%
hideGroup(c("perim","cnty", "sid74"))
###
Then, you get 4 objects (maps) we can compare their size directly in R:
object.size(one_layer)
301864 bytes
object.size(two_layers)
531144 bytes
object.size(three_layers)
681872 bytes
object.size(four_layers)
828616 bytes
The size increase is constant and way higher that what we would expect if the only the data was added instead of all the spatial info. As a comparison, the initial shape which has 15 fields is of size:
object.size(nc)
135360 bytes
If we save the maps to HTML, the problem is even more visible:
saveWidget(one_layer, paste0(getwd(),"/temp_data/temp/one_layer.html"), selfcontained = F)
saveWidget(two_layers, paste0(getwd(),"/temp_data/temp/two_layers.html"), selfcontained = F)
saveWidget(three_layers, paste0(getwd(),"/temp_data/temp/three_layers.html"), selfcontained = F)
saveWidget(four_layers, paste0(getwd(),"/temp_data/temp/four_layers.html"), selfcontained = F)
file.info(list.files("temp_data/temp", pattern = ".html$", full.names = T))$size[c(2,4,3,1)] %>%
setNames(c("One Layer", "Two Layers", "Three Layers", "Four Layers")) %>%
barplot(ylab="size in Bytes")
It's clearly doubling in size.
So, to summarize, is there a way to get leaflet to not reproduced the spatial information when adding multiple fields of data to the same map?
I am making an R leaflet map (not Shiny) and I have two control groups, and based on the selection I would like a different legend to become visible. Currently I only manage to have both legends visible at all time.
Below is the code for the leaflet map, and the output can be seen in the image.
leaflet() %>% addSearchOSM() %>%
addProviderTiles(providers$CartoDB.Positron,
options = providerTileOptions(noWrap = TRUE),
group = "kaart") %>%
# addFullscreenControl() %>%
addCircleMarkers(data = table#data,
lat = ~lng,
lng = ~lat,
color = ~palverbruikplaats(Verbruiksplaats),
label = bepaalPopup(),
group = "Verbruikplaatscircles"
)%>%
addCircleMarkers(data = table#data,
lat = ~lng,
lng = ~lat,
color = ~palstatus(`Status omschrijving`),
label = bepaalPopup(),
group = "statuscircles"
)%>%
leaflet::addLegend("bottomleft", pal = palverbruikplaats, values = verbruikplaatsuniek, title = "Legenda") %>%
leaflet::addLegend("bottomleft", pal = palstatus, values = statusuniek, title = "Legenda") %>%
addLayersControl(baseGroups = c("Verbruikplaatscircles", "statuscircles"),
options = layersControlOptions(collapsed = FALSE))
In your addLayersControl did you mean to set the overlayGroups argument instead of baseGroups?
library(leaflet)
leaflet() %>%
addTiles(group = "OpenStreetMap") %>%
addCircleMarkers(runif(20, -75, -74), runif(20, 41, 42), group = "Markers1", color ="red") %>%
addMarkers(runif(20, -75, -74), runif(20, 41, 42), group = "Markers2") %>%
addLegend(values = 1, group = "Markers1", position = "bottomleft", labels = "1", colors= "red") %>%
addLegend(values = 2, group = "Markers2", position = "bottomleft", labels = "2" ,colors= "blue") %>%
addLayersControl(overlayGroups = c("Markers1", "Markers2"),
options = layersControlOptions(collapsed = FALSE))
what you need to do is, you need to make your legends values reactive
addLegend("bottomright", pal = pal, values = maindata#data[,req_var1()],
you can declare the req_var1() in server before calling
req_var1<-reactive({if(input$`Comparison Metric`=="Current Territory Factors vs GeoProxy Smoothing"){
paste(input$Curr2,"Curr",sep="_")
} else if(input$`Comparison Metric`=="Current Written Premium Vs Indicated Written Premium"){
paste(input$Curr2,"CWP",sep="_")
}
})
and also the pal can be declared as
pal1 <- reactive({if(input$ColorType=="Percentile"){
colorQuantile(
palette = "Spectral",
domain = tempdata()#data[,req_var1()],
probs = if(input$`Comparison Metric`=="Current Territory Factors vs GeoProxy Smoothing"){seq(0,1,by=0.25)
} else if(input$`Comparison Metric`=="Current Written Premium Vs Indicated Written Premium"){
seq(0,1,by=0.5)
}
## In case of Current written premium the variation is very less so while executing color mapping code is throwing error.
## This is because the some of quantiles values are not differentiable.
## So in colorQuantile function we have given two different prob values depending on metric selection.
)
} else if(input$ColorType=="Absolute Value"){colorNumeric(
palette = "Spectral",
domain = tempdata()#data[,req_var1()])
}else{print("Plese select Any one color map")}
})
I am trying to write a script that would allow people to click on a country then a popup would appear and show the country's name and corresponding value. I have successfully created the map and the boundaries of each country, however when you click on, for example Russia, the popup would show India. Below is a simplified version of the script:
library(leaflet)
library(maps)
countries <- c("Australia", "South Africa", "India", "Mexico", "USA", "Russia")
values <- c(1,2,3,4,5,6)
bounds <- map("world", countries, fill = TRUE, plot = FALSE)
map <- leaflet(data) %>%
addTiles() %>%
addPolygons(data = bounds, group = "Countries",
color = "red",
weight = 2,
popup = paste("Country: ", countries, "<br>", "Value: ", values, "<br>"),
fillOpacity = 0.1,
highlightOptions = highlightOptions(color = "black",
weight = 2,
bringToFront = TRUE))
map
The map is generated using the leaflet package in R. Any solutions or advice would be welcome, I am sure it is a simple error that I am making somewhere.
I leave two options for you. If you just want to show the country names as they are in bounds (e.g., Australia:Melville Island), you need to change popup = countries to popup = ~names.
map1 <- leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addPolygons(data = bounds, group = "Countries",
color = "red",
weight = 2,
popup = ~names,
fillOpacity = 0.1,
highlightOptions = highlightOptions(color = "black",
weight = 2,
bringToFront = TRUE))
If you want to just have the country names as you specified in countries, you want to manipulate names using gsub(), for example. Here I removed all characters from : to the end for each name.
map2 <- leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addPolygons(data = bounds, group = "Countries",
color = "red",
weight = 2,
popup = ~gsub(x = names, pattern = ":.*$", replacement = ""),
fillOpacity = 0.1,
highlightOptions = highlightOptions(color = "black",
weight = 2,
bringToFront = TRUE))
EXTRA
The OP added one more thing to his question. Here is my idea. If you have two things to show in popups, you can do the following. You add value to bounds and create popups.
# Add values to bounds.
set.seed(111)
bounds$value <- sample.int(n = 1000, size = 301, replace = TRUE)
map3 <- leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addPolygons(data = bounds, group = "Countries",
color = "red",
weight = 2,
popup = paste("Country: ", bounds$names, "<br>",
"Value: ", bounds$value, "<br>"),
fillOpacity = 0.1,
highlightOptions = highlightOptions(color = "black",
weight = 2,
bringToFront = TRUE))
When I try to add a legend to a leaflet map for a leaflet map (using the Leaflet for R package) incorporated into a Shiny app, the legend does not show the colors of the color palette. Instead it only shows the colors specified for the NA values, in this case, white.
The app does the following:
First, it filters a set of data based on user inputs
Then it generates a choropleth map from the filtered data
This is the code I used to make the legend:
addLegend(position = "bottomleft",
pal = pal, values = shp.data()$stat.selected,
title = "Legend",
opacity = .5)
Where pal is a quantile color palette as follows
pal <-colorQuantile(c("#B2FF66","#66CC00","#4C9900","#336600","#193300"),
NULL, n = 5, na.color="#FFFFFF")
shp.data() is a reactive expression that is a shapefile filtered based on user inputs and stat_selected is the specific statistic that the user selects for mapping onto colors.
I get the following warnings:
Warning in is.na(x) :
is.na() applied to non-(list or vector) of type 'NULL'
Warning in is.na(values) :
is.na() applied to non-(list or vector) of type 'NULL'
I initially tried to make the legend following the example on the leaflet for R page and used the argument values = ~stat.selected for the addLegend function, but I got this error:
Error in UseMethod("doResolveFormula") :
no applicable method for 'doResolveFormula' applied to an object of class "NULL"
Earlier I had just a simple snippet that showed how to add legends. I did not use the ~ before the legend values as is the norm. I did the traditional dataframe$column and it works nicely.
This is now updated to see how it all fits together. Here is a full-fledged mapping run after creating all of the variable cuts, etc. The final cleansed data frame was called zipData
# create a full popup
# add some HTML for editing the styles
zipData$popUp <- paste('<strong>',zipData$Street, '</strong><br>',
'TIV = $',prettyNum(zipData$tiv, big.mark = ',',preserve.width = 'none'), '<br>',
'City: ', zipData$city, '<br>',
'YrBuilt = ', zipData$YearBuilt, '<br>',
'Construction = ', zipData$ConstructionCode, '<br>',
'Occupancy = ', zipData$OccupancyCode, '<br>',
'Premium = $' , prettyNum(zipData$Premium, big.mark = ',',preserve.width = 'none') , '<br>',
'GrossArea = ', prettyNum(zipData$GrossArea, big.mark = ',', preserve.width = 'none'), '<br>',
'RoofYr = ', zipData$RoofYearBuilt, '<br>')
# set color scale for key factor
colorsConst <- colorFactor(rainbow(4), zipData$ConstructionCode)
# color scales for numerical bins
colorstivValue <- colorFactor(palette = 'Accent', zipData$tivValueLvl)
colorsYrBuilt <- colorFactor(palette = 'Spectral', zipData$yrBuiltLvl)
colorsRoofYrBuilt <- colorFactor(palette = "YlOrRd", zipData$roofYrBuiltLvl)
# begin the leaflet map construction
# create the map opbject
m <- leaflet() %>%
addTiles() %>%
# add different tiles for different color schemes
addProviderTiles(providers$OpenStreetMap, group = 'Open SM') %>%
addProviderTiles(providers$Stamen.Toner, group = 'Toner') %>%
addProviderTiles(providers$CartoDB.Positron, group = 'CartoDB') %>%
addProviderTiles(providers$Esri.NatGeoWorldMap, group = 'NG World') %>%
setView(lng = -90, lat = 30, zoom = 10) %>%
##############################
# this section is for plotting the variables
# each variable below is a layer in the map
# construction
addCircleMarkers(data = zipData, lat = ~Lat, lng = ~Lon,
color = ~colorsConst(ConstructionCode), popup = zipData$popUp,
radius = 5, group = 'Construction') %>%
# tiv
addCircleMarkers(data = zipData, lat = ~Lat, lng = ~Lon,
color = ~colorstivValue(tivLvl), popup = zipData$popUp,
radius = ~tiv/20000, group = 'Bldg Value') %>%
# year built
addCircleMarkers(data = zipData, lat = ~Lat, lng = ~Lon,
color = ~colorsYrBuilt(yrBuiltLvl), popup = zipData$popUp,
radius = ~YearBuilt/250, group = 'Yr Built') %>%
######################################
# layer control
addLayersControl(
baseGroups = c('Open SM', 'Toner', 'Carto DB', 'NG World'),
overlayGroups = c('Construction',
'TIV',
'Yr Built'
),
options = layersControlOptions(collapsed = F)
) %>%
#################################################
add the legends for each of the variables
# construction
addLegend('bottomright', pal = colorsConst, values = zipData$ConstructionCode,
title = 'Construction Code',
opacity = 1) %>%
# tiv
addLegend('bottomleft', pal = colorstivValue, values = zipData$tivLvl,
title = 'TIV',
opacity = 1) %>%
# year built
addLegend('topleft', pal = colorsYrBuilt, values = zipData$yrBuiltLvl,
title = 'Yr Built',
opacity = 1)
m # Print the map
A portion of the map is shown below.
I was able to make the colors showing up by changing the way I was referencing the values column in the arguments of the AddLegend function. I put the stat.selected variable in double brackets, which seemed to fix the problem:
addLegend(position = "bottomleft",
pal = pal, values = shp.data()[[stat.selected]],
title = "Legend",
opacity = 1
)
For clarification, the stat.selected variable comes from the following switch statement:
stat.selected <- isolate(switch(input$var.stat,
"Total employment" = "tot_emp",
"Mean annual wage" = "a_mean",
"Mean hourly wage" = "h_mean",
"Location quotient" = "loc_quotient"
)
where "tot_emp", "a_mean", "h_mean", and "loc_quotient" are column names in the shp.data spatial polygons data frame.
I guess the problem was that I was trying to pass in the column name by variable using a $.
I'm still a fairly novice R user, so if anyone can explain why the example in the Leaflet for R documentation does not work in this case I would appreciate it.
I had the same message
Error in UseMethod("doResolveFormula") : no applicable method for 'doResolveFormula' applied to an object of class "NULL"
with
data <- data.frame(lng1 = c(1, 2, 3),
lng2 = c(2, 3, 4),
lat1 = c(1, 2, 3),
lat2 = c(2, 3, 4),
values = c(1, 2, 3))
pal_grid <- colorNumeric(palette = "YlGn", domain = data$values)
leaflet() %>%
addRectangles(lng1 = data$lng1, lat1 = data$lat1,
lng2 = data$lng2, lat2 = data$lat2,
fillColor = ~pal_grid(data$values),
fillOpacity = 0.2,
weight = 2, opacity = 0.5)
The solution is to provide to leaflet the data that you are using to create the element in the main call to leaflet() or in the call to any element that you add after that.
In the main call to leaflet():
data <- data.frame(lng1 = c(1, 2, 3),
lng2 = c(2, 3, 4),
lat1 = c(1, 2, 3),
lat2 = c(2, 3, 4),
values = c(1, 2, 3))
pal_grid <- colorNumeric(palette = "YlGn", domain = data$values)
leaflet(data = data) %>%
addRectangles(lng1 = data$lng1, lat1 = data$lat1,
lng2 = data$lng2, lat2 = data$lat2,
fillColor = ~pal_grid(data$values),
fillOpacity = 0.2,
weight = 2, opacity = 0.5)
At the moment of add elements:
data <- data.frame(lng1 = c(1, 2, 3),
lng2 = c(2, 3, 4),
lat1 = c(1, 2, 3),
lat2 = c(2, 3, 4),
values = c(1, 2, 3))
pal_grid <- colorNumeric(palette = "YlGn", domain = data$values)
leaflet() %>%
addRectangles(data = data,
lng1 = data$lng1, lat1 = data$lat1,
lng2 = data$lng2, lat2 = data$lat2,
fillColor = ~pal_grid(data$values),
fillOpacity = 0.2,
weight = 2, opacity = 0.5)`