leaflet side-by-side for 2 raster images in R - r

{leaflet.extras2} implements the leaflet side-by-side plugin and provides this minimal example:
library(leaflet)
library(leaflet.extras2)
leaflet(quakes) %>%
addMapPane("left", zIndex = 0) %>%
addMapPane("right", zIndex = 0) %>%
addTiles(group = "base", layerId = "baseid",
options = pathOptions(pane = "right")) %>%
addProviderTiles(providers$CartoDB.DarkMatter, group="carto", layerId = "cartoid",
options = pathOptions(pane = "left")) %>%
addCircleMarkers(data = breweries91[1:15,], color = "blue", group = "blue",
options = pathOptions(pane = "left")) %>%
addCircleMarkers(data = breweries91[15:20,], color = "yellow", group = "yellow") %>%
addCircleMarkers(data = breweries91[15:30,], color = "red", group = "red",
options = pathOptions(pane = "right")) %>%
addLayersControl(overlayGroups = c("blue","red", "yellow")) %>%
addSidebyside(layerId = "sidecontrols",
rightId = "baseid",
leftId = "cartoid")
However, when adapting to two raster images, I encounter the error:
Error in addRasterImage(., r2, colors = pal2, options = pathOptions(pane = "right"), :
unused argument (options = pathOptions(pane = "right"))
Here is a reproducible example:
library(raster)
library(leaflet)
library(leaflet.extras2)
library(rcartocolor)
# example raster data
r1 <- r2 <- raster(system.file("external/test.grd", package = "raster"))
# color palettes
pal1 <- colorNumeric(carto_pal(name = "OrYel"),
values(r1), na.color = "transparent")
pal2 <- colorNumeric(carto_pal(name = "BluYl"),
values(r2), na.color = "transparent")
# side by side map
leaflet() %>%
addMapPane("left", zIndex = 0) %>%
addMapPane("right", zIndex = 0) %>%
addTiles(group = "base", layerId = "baseid",
options = pathOptions(pane = "right")) %>%
addTiles(group = "carto", layerId = "cartoid",
options = pathOptions(pane = "left")) %>%
addRasterImage(r1, colors = pal1,
options = pathOptions(pane = "right"), group = "r1") %>%
addRasterImage(r2, colors = pal2,
options = pathOptions(pane = "right"), group = "r2") %>%
addLayersControl(overlayGroups = c("r1", "r2")) %>%
addSidebyside(layerId = "sidecontrols",
rightId = "baseid",
leftId = "cartoid")

The solution is pointed here by #RexParsons.
You will need addRasterImage's options = leafletOptions(pane = "") that will be added to {leaflet} on next release.
Step 1: for now you can install raster-options:
remotes::install_github("rstudio/leaflet", ref="joe/feature/raster-options")
Step 2: Session -> Restart R
Step 3: add options = leafletOptions(pane = ""):
leaflet() |>
addMapPane("right", zIndex = 0) |>
addMapPane("left", zIndex = 0) |>
addTiles(group = "base", layerId = "baseid1", options = pathOptions(pane = "right")) |>
addTiles(group = "base", layerId = "baseid2", options = pathOptions(pane = "left")) |>
addRasterImage(x = r1, colors = pal1, options = leafletOptions(pane = "right"), group = "r1") |>
addRasterImage(x = r2, colors = pal2, options = leafletOptions(pane = "left"), group = "r2") |>
addLayersControl(overlayGroups = c("r1", "r2")) |>
addSidebyside(layerId = "sidecontrols",
rightId = "baseid1",
leftId = "baseid2")
Output:
Option 2 (with addProviderTiles):
leaflet() |>
addMapPane("right", zIndex = 0) |>
addMapPane("left", zIndex = 0) |>
addTiles(group = "base", layerId = "baseid", options = pathOptions(pane = "right")) |>
addProviderTiles(providers$CartoDB, group="carto", layerId = "cartoid", options = pathOptions(pane = "left")) |>
addRasterImage(x = r1, colors = pal1, options = leafletOptions(pane = "right"), group = "r1") |>
addRasterImage(x = r2, colors = pal2, options = leafletOptions(pane = "left"), group = "r2") |>
addLayersControl(overlayGroups = c("r1", "r2")) |>
addSidebyside(layerId = "sidecontrols",
rightId = "baseid",
leftId = "cartoid")
Output:
Does it work for you?
<-- Partial answer to the #oatmilkyway's question below -->
Someone need to find a way to (conditionally) add/remove the leaflet.extras2::addSidebyside's layerId's, as one of possible solutions (if already exists, please let me know).
leaflet() |>
addMapPane("right", zIndex = 0) |>
addMapPane("left", zIndex = 0) |>
addTiles(group = "Base map", layerId = "baseid1", options = pathOptions(pane = "right")) |>
addTiles(group = "Base map", layerId = "baseid2", options = pathOptions(pane = "left")) |>
addProviderTiles(provider = providers$Esri.WorldImagery, group = "Satellite map", layerId = "satelliteid1", options = pathOptions(pane = "right")) |>
addProviderTiles(provider = providers$Esri.WorldImagery, group = "Satellite map", layerId = "satelliteid2", options = pathOptions(pane = "left")) |>
addRasterImage(x = r1, colors = pal1, options = leafletOptions(pane = "right"), group = "raster image 1") |>
addRasterImage(x = r2, colors = pal2, options = leafletOptions(pane = "left"), group = "raster image 2") |>
addLayersControl(baseGroups = c("Base map", "Satellite map"),
overlayGroups = c("raster image 1", "raster image 2")) |>
addSidebyside(layerId = "sidecontrols2", rightId = "satelliteid1", leftId = "satelliteid2") |>
addSidebyside(layerId = "sidecontrols", rightId = "baseid1", leftId = "baseid2")
leaflet() |>
addMapPane("right", zIndex = 0) |>
addMapPane("left", zIndex = 0) |>
addTiles(group = "Base and Carto Positron maps", layerId = "baseid", options = pathOptions(pane = "right")) |>
addProviderTiles(provider = providers$CartoDB.Positron, group = "Base and Carto Positron maps", layerId = "cartoid", options = pathOptions(pane = "left")) |>
addProviderTiles(provider = providers$Esri.WorldImagery, group = "Satellite and Toner Lite maps", layerId = "satelliteid", options = pathOptions(pane = "right")) |>
addProviderTiles(provider = providers$Stamen.TonerLite, group = "Satellite and Toner Lite maps", layerId = "tonerlightid", options = pathOptions(pane = "left")) |>
addRasterImage(x = r1, colors = pal1, options = leafletOptions(pane = "right"), group = "raster image 1") |>
addRasterImage(x = r2, colors = pal2, options = leafletOptions(pane = "left"), group = "raster image 2") |>
addLayersControl(baseGroups = c("Base and Carto Positron maps", "Satellite and Toner Lite maps"),
overlayGroups = c("raster image 1", "raster image 2"),
options = layersControlOptions(collapsed = FALSE)) |>
addSidebyside(layerId = "sidecontrols2", rightId = "satelliteid", leftId = "tonerlightid") |>
addSidebyside(layerId = "sidecontrols", rightId = "baseid", leftId = "cartoid")
Output:
Although this is a clunky answer at best, I hope it may help you.

Related

How to fix "No scattergeo mode specifed: Setting the mode to markers" error message?

I am working on the following code
athletes %>%
rename(sport = Discipline) %>%
group_by(country) %>%
summarize(number_of_athletes = n()) %>%
mutate(hover = paste0(country,"\n","Number of Athletes: ", number_of_athletes)) %>%
plot_geo(type = "choropleth") %>%
add_trace(locations = ~country,
locationmode = "country names",
z = ~number_of_athletes,
colorscale = "Portland",
text = ~hover,
hoverinfo = "text",
marker = list(line = list(color = "gray50"))) %>%
layout(title = list(text = "Number of Athletes by Country", font = list(size = 20), xanchor = "center", yanchor = "middle"),
width = 900,
height = 500,
margin = list(b = 10),
dragmode = FALSE,
showlegend = TRUE) %>%
colorbar(title = "Number of Athletes") %>%
config(displayModeBar = FALSE)
I receive: No scattergeo mode specifed: Setting the mode to markers /
Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
I tried to fix using type = 'scatter', mode = 'markers' the message still appears. Any idea?

Bar with negative stack and positive labels

I'm trying to make in R (Shiny) a reversed stacked bar highchart. I already found how to make the graph, but I can't find out how to make the labels on the x-axis positive, like here: https://www.highcharts.com/demo/bar-negative-stack
I've tried to apply the abs() function, but it didn't work so far. Does anyone have a solution?
highchart() %>%
hc_chart(type = "bar") %>%
hc_title(text = "Example") %>%
hc_yAxis(title = list(text = ""), labels = list(format = "{value}")) %>%
hc_plotOptions(series=list(stacking='normal'),
column = list( dataLabels = list(enabled = FALSE),
enableMouseTracking = TRUE)) %>%
hc_legend(enabled = FALSE) %>%
hc_xAxis(reversed=FALSE, opposite=TRUE, reversed=FALSE) %>%
hc_add_series(name="neutral", id='neutral', color=c("#766A62"), data=list(2, 8)) %>%
hc_add_series(name="Neutral",linkedTo='neutral',color=c("#ffeeff"),data=list(-5, -3))
I want the values of the bars and the labels on the x-axis all to be positive. Any ideas welcome.
Using your code:
highchart() %>%
hc_chart(type = "bar") %>%
hc_title(text = "Example") %>%
hc_yAxis(title = list(text = ""),labels = list(format = "{value}")) %>%
hc_plotOptions(series=list(stacking='normal'),column = list( dataLabels = list(enabled = FALSE),
enableMouseTracking = TRUE)) %>%
hc_legend(enabled = FALSE) %>%
hc_xAxis(list(categories = c("0-4", "5-9"),
reversed=FALSE ),
list(reversed=FALSE,opposite=TRUE,
reversed=FALSE,
categories =c("0-4", "5-9"),
linkedTo = 0)) %>%
hc_yAxis(
labels = list(
formatter = JS("function(){ return Math.abs(this.value) + '%'; }"))) %>%
hc_add_series(name="neutral",id='neutral',color=c("#766A62"),data=list(2, 8)) %>%
hc_add_series(name="Neutral",linkedTo='neutral',color=c("#ffeeff"),data=list(-5, -3))
Following lines are modified:
hc_xAxis(list(categories = c("0-4", "5-9"),
reversed=FALSE ),
list(reversed=FALSE,opposite=TRUE,
reversed=FALSE,
categories =c("0-4", "5-9"),
linkedTo = 0)) %>%
hc_yAxis(
labels = list(
formatter = JS("function(){ return Math.abs(this.value) + '%'; }")))
Result:

R Leaflet Label Set direction

Please have a look at the below example code, I would like to use the label direction (MyDirection), which is stored in df to have different label directions within my map.
I can set every label to a specific direction like direction = "top", but somehow its not working if I specify direction = ~MyDirection.
Any Idea/solution would be much appreciated.
Thanks in advance.
library(leaflet)
df <- read.csv(textConnection("
Name,Lat,Long,MyDirection
ANN,51.19,4.46277778,right
BAB,43.26306,-2.94972222,left
BCN,41.29694,2.07833333,top
BCN,41.29694,2.07833333,bottom
"))
#---Create Map----
m <- leaflet(df) %>%
addTiles(group = "OSM (default)") %>%
addCircles(~Long, ~Lat,
label = ~htmlEscape(Name),
labelOptions = labelOptions(noHide = T,
#direction = "top",
#direction = "bottom",
#direction = "left",
#direction = "right",
direction = ~MyDirection))
m
I would like to share my latest approach. I finally managed to set the label direction based on mydf$MyDirection. Instead of adding multiple layers, as i did in my previous example, I used the library "Purrr". This reduces the amount of layers tremendously.
Best Regards
#Libraries----
library(leaflet)
library(htmltools)
library(htmlwidgets)
library(purrr)
#---Data Input----
mydf <- read.csv(textConnection("
Facility,Lat,Long,MyDirection
ANN,51.19,4.46277778,right
BAB,43.26306,-2.94972222,left
BCN,41.29694,2.07833333,top
BCN2,41.29694,2.07833333,bottom
"))
#---Create Vector----
ob_Facility <- mydf %>%
split(., .$Facility)
#---Create Map----
m <- leaflet() %>%
addTiles()
#---Purrr Layers----
names(ob_Facility) %>%
purrr::walk(function(mydf) {
m <<- m %>%
addCircleMarkers(data=ob_Facility[[mydf]],
lng=~Long, lat=~Lat,
group = "Show All",
label = ~Facility,
labelOptions = labelOptions(noHide = T,direction = ~MyDirection))
})
#---Layers control----
m %>%
addLayersControl(
overlayGroups = "Show All",
options = layersControlOptions(collapsed = FALSE)
)%>%
#---Save as HTML File----
saveWidget('Example Go Live Date.html', selfcontained = TRUE)
Hello,
I have figured out a workaround with 4 Layers (top,bottom,left,right) and attached the same group name to each layer.
library(leaflet)
df <- read.csv(textConnection("
Name,Lat,Long,MyDirection
ANN,51.19,4.46277778,right
BAB,43.26306,-2.94972222,left
BCN,41.29694,2.07833333,top
BCN,41.29694,2.07833333,bottom
"))
#---Create 4 additional DFs (1 for each dirction)----
dfLeft = df[df$MyDirection == "left", ]
dfRight = df[df$MyDirection == "right", ]
dfTop = df[df$MyDirection == "top", ]
dfBottom = df[df$MyDirection == "bottom", ]
#---Create Map----
m <- leaflet(df) %>%
addTiles(group = "OSM (default)") %>%
addCircles(~dfLeft$Long, ~dfLeft$Lat, color = '#d40511',
label = ~htmlEscape(dfLeft$Name),
labelOptions = labelOptions(noHide = T,
direction = "left"),
group = "Show All")%>%
addCircles(~dfRight$Long, ~dfRight$Lat, color = '#d40511',
label = ~htmlEscape(dfRight$Name),
labelOptions = labelOptions(noHide = T,
direction = "right"),
group = "Show All")%>%
addCircles(~dfTop$Long, ~dfTop$Lat, color = '#d40511',
label = ~htmlEscape(dfTop$Name),
labelOptions = labelOptions(noHide = T, direction = "top",
offset = c(0, -2)),
group = "Show All")%>%
addCircles(~dfBottom$Long, ~dfBottom$Lat, color = '#d40511',
label = ~htmlEscape(dfBottom$Name),
labelOptions = labelOptions(noHide = T, direction = "bottom",
offset = c(0, 2)),
group = "Show All")
m

Weird Leaflet Map Legend Display

pal <- colorFactor(palette = "Set1", domain = MFT_tidy$Parent_Organization)
popup_text <- paste(MFT_tidy$Facility_Name, "<br>",
"Facility_Phone:", MFT_tidy$Facility_Phone, "<br>",
"Vendor_Name:", MFT_tidy$Vendor_Name)
layer_groups <- c("OSM (default)", "Toner", "Positron", "NatGeoWorldMap")
leaflet(MFT_tidy, width = "100%") %>%
addTiles(group = "OSM (default)") %>%
addProviderTiles(providers$Stamen.Toner, group = "Toner") %>%
addProviderTiles(providers$CartoDB.Positron, group = "Positron") %>%
addProviderTiles(providers$OpenTopoMap, group = "OpenTopoMap") %>%
addProviderTiles(providers$Esri.NatGeoWorldMap, group = "NatGeoWorldMap") %>%
addCircleMarkers(lng = ~longitude, lat = ~latitude,
color = ~pal(Parent_Organization),
stroke = FALSE, fillOpacity = 1,
label = ~Facility_Name,
popup = popup_text,
clusterOptions = markerClusterOptions() ) %>%
addLegend(position = "topright", pal = pal,
values = ~Parent_Organization,
labels = ~Parent_Organization,
title = "Parent Organization",
opacity = 1) %>%
addLayersControl(baseGroups = c("OSM (default)", "Toner", "Positron",
"OpenTopoMap", "NatGeoWorldMap"),
position = "bottomright") %>%
addMeasure(
position = "bottomleft",
primaryLengthUnit = "meters",
primaryAreaUnit = "sqmeters",
activeColor = "#3D535D",
completedColor = "#7D4479") %>%
addEasyButton(easyButton(
icon = "fa-globe", title = "Zoom to Original Level",
onClick = JS("function(btn, map){ map.setZoom(6); }"))) %>%
addEasyButton(easyButton(
icon = "fa-crosshairs", title = "Locate Me",
onClick = JS("function(btn, map){ map.locate({setView: true}); }")))
The code I used to create the map is as above:
There are obvious something wrong with the weird display of legend. I do not know how to correct it. I really cannot find anything wrong in the addLegend function.
Possible duplicate.
Problem is not with the addLegend function, but rather the zoom in the browser. You can fix this by adjusting CSS on the legend
Copying #Adam's code:
ui <- bootstrapPage(
tags$style(type="text/css", "div.info.legend.leaflet-control br {clear: both;}"),
...
)

R Leaflet: Zoom Control Level

I am trying to set zoom out maximum in my R Leaflet map. I follow an example of a previous question/answer in Prevent zooming out in leaflet R-Map? , but it doesn't work. The line that should be able to do this is:
options = providerTileOptions(minzoom = 1, maxzoom = 10))
Can you guys can help me to figure out why?
Here is code:
deck_lf_par_map <- leaflet(lpoints) %>%
addPolygons(data = dio, noClip=T,
weight = 4,
dashArray="5, 1",
color = "black",
fillOpacity = .01,
smoothFactor = 0) %>%
setView(lng = mean(lpoints$long), lat = mean(lpoints$lat), zoom = 09) %>%
addProviderTiles("Stamen.TonerLite",
group = "Toner",
options = providerTileOptions(minzoom = 1, maxzoom = 10)) %>%
addTiles(group = "OSM") %>%
addProviderTiles("Esri.WorldTopoMap",
group = "Topo") %>%
addProviderTiles("OpenStreetMap.Mapnik", group = "Mapnik") %>%
addProviderTiles("CartoDB.Positron", group = "CartoDB") %>%
setMaxBounds((dioc#bbox[1,1] - .3),
(dioc#bbox[2,1] - .3),
(dioc#bbox[1,2] + .3),
(dioc#bbox[2,2] + .3)) %>%
addMarkers(lpoints$long,
lpoints$lat,
popup=ppopup,
icon = tec_icon,
group="Parishes",
clusterOptions = markerClusterOptions()) %>%
addLayersControl(baseGroups = c("Toner", "OSM", "Topo", "Mapnik", "CartoDB"),
options = layersControlOptions(collapsed = TRUE))
A couple of points:
It's minZoom and maxZoom (notice the capital Z)
You need the options in each Tile function that you want to set
the zoom levels for.
library(leaflet)
## the first two tiles have a zoom level control - the others don't
leaflet() %>%
setView(lng = 144, lat = -37, zoom = 09) %>%
addProviderTiles("Stamen.TonerLite",
group = "Toner",
options = providerTileOptions(minZoom = 8, maxZoom = 10)) %>%
addTiles(group = "OSM",
options = providerTileOptions(minZoom = 8, maxZoom = 10)) %>%
addProviderTiles("Esri.WorldTopoMap",
group = "Topo") %>%
addProviderTiles("OpenStreetMap.Mapnik", group = "Mapnik") %>%
addProviderTiles("CartoDB.Positron", group = "CartoDB") %>%
addLayersControl(baseGroups = c("Toner", "OSM", "Topo", "Mapnik", "CartoDB"),
options = layersControlOptions(collapsed = TRUE))

Resources