Cluster color in leaflet Heatmap - r

Is there a way how to have cluster colors in leaflets addHeatmap function, let say we have some values of variables and cluster them to 8 categories (see example), is there a way how to have also 8 color categories in the heatMap? I know this can be done in ggplot - geom_geom_tile
Is there a way ho to reproduce it in leaflet as well?
Example:
library(ggmap)
library(maptools)
library(ggplot2)
d = data.frame(
pred_res = runif(2000, -2, 2),
lat = runif(2000, 49.94, 50.18),
lon = runif(2000, 14.22, 14.71)
)
#top&bottom coding and discreting pred_res....8
d$res_coded<-replace(d$pred_res,d$pred_res<(-1),8)
d$res_coded<-replace(d$res_coded,d$pred_res>=-1,7)
d$res_coded<-replace(d$res_coded,d$pred_res>=-0.4,6)
d$res_coded<-replace(d$res_coded,d$pred_res>=-0.1,5)
d$res_coded<-replace(d$res_coded,d$pred_res>=0,4)
d$res_coded<-replace(d$res_coded,d$pred_res>=0.1,3)
d$res_coded<-replace(d$res_coded,d$pred_res>=0.4,2)
d$res_coded<-replace(d$res_coded,d$pred_res>=1,1)
d %>% head
d$res_coded %>% table
library(leaflet)
library(leaflet.extras)
leaflet() %>% addProviderTiles("CartoDB.Positron") %>%
addHeatmap(lng = d$lon, lat = d$lat, intensity = d$res_coded)

Please see the gradient function from the documentation here.
Here is an example with a different color palette:
leaflet() %>% addProviderTiles("CartoDB.Positron") %>%
addHeatmap(lng = d$lon, lat = d$lat, intensity = d$res_coded, gradient="RdYlGn")

Related

Curved flow lines in leaflet minicharts R

I'm creating a flow map in R Leaflet which will eventually go through Shiny. This is a very simplified example of what it looks like:
How can I curve the flow lines?
Reproducible example:
library(leaflet)
library(leaflet.minicharts)
library(tidyverse)
dat <- data.frame(
Origin_lat = c(40.15212, 40.65027),
Origin_lng = c(-74.79037, -74.91990),
Dest_lat = c(40.78749, 40.78749),
Dest_lng = c(-73.96188, -73.96188),
flow = c(237, 84)
)
leaflet() %>%
addProviderTiles(providers$Esri.WorldGrayCanvas) %>%
setView(lat = 40.39650, lng = -74.39541, zoom = 9) %>%
addFlows(
lng0 = dat$Origin_lng,
lat0 = dat$Origin_lat,
lng1 = dat$Dest_lng,
lat1 = dat$Dest_lat,
flow = dat$flow
)
There is a package geosphere which has the functions which you need
This should get you where you need to be, you can pass it either a matrix for start and stop with X,Y in each or a vector for each type of coordinate, as here
library(geosphere) #install as needed
gcIntermediate(c(Origin_lat,Origin_lng), c(Dest_lat,Dest_lng),
n=80, #how many curve points along lines
addStartEnd=TRUE,
sp=TRUE ) %>%
leaflet() %>%
addTiles() %>%
addPolylines()
If it were me, I would restructure the points to be able to pass: origin & destination as two-column matrices of Lat, Lon values, but it should work as vectors too.

Map vector group in specific order - R leaflet

I have a shapefile with polylines of routes in different years. Here is an example data shapefile with routes in the year 2000 and year 2013. I would like the map to show the older routes at the top and more recent routes at the bottom. I've had a look at the addMapPane function but not sure how to apply it for a vector in the same file. Here is my code so far:
sample_palette <- leaflet::colorFactor(palette = rainbow(2),
domain = data_sample$Year)
sample_plot <- leaflet(data_sample) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolylines(color = ~sample_palette(Year),
opacity = 1) %>%
leaflet::addLegend(values = ~Year,
opacity = 1,
pal = sample_palette,
title = "Routes")
sample_plot
I am using leaflet and R.
Please find one possible solution to get the older routes on top of recent routes: just need to change the order of rows in data_sample
Code
library(sf)
library(leaflet)
data_sample <- st_read("ADD YOUR PATH HERE")
# Order 'data_sample' rows in decreasing order of 'Year'
data_sample <- data_sample %>%
arrange(., desc(Year))
# Choose colors
sample_palette <- leaflet::colorFactor(palette = rainbow(2),
domain = data_sample$Year)
# Build the map
sample_plot <- leaflet(data_sample) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolylines(color = ~sample_palette(Year),
opacity = 1) %>%
leaflet::addLegend(values = ~Year,
opacity = 1,
pal = sample_palette,
title = "Routes")
Visualization
sample_plot

Adding images to maps with Leafpop

I'm trying to add separate images to popups so that as you click on each location, an image specific to that place/popup appears. I've figured out how to get one image in, but it applies to all of the popups on the map instead of just one. I have been trying to use the package leafpop for this, but I can't really figure out how to make it work. Even if I just use one image, nothing appears on the map.
This is what my code looks like for it:
library(leaflet)
library(leafpop)
img = system.file("file/image_name.jpg", package = "jpg")
leaflet(map) %>%
addTiles() %>%
addCircleMarkers(label = map#data$name,
weight = 2,
color = "grey",
fillColor = "red",
fillOpacity = 0.7)%>%
addPopupImages(img, group = "map")
I know there's some bits in there that I'm not quite doing right. At this point, I just want to know if it's even possible to do this the way I'm envisioning. Any help is appreciated.
The images need to be in a vector of the same length as the points passed to leaflet. Here is a reproducible example you can copy paste that will get you started:
library(tidyverse)
library(sf)
library(leaflet)
library(leafpop)
pts <- tibble(x = runif(10, 175, 176),
y = runif(10, -38, -37)) %>%
st_as_sf(coords = c("x", "y"), crs = 4326)
img <- glue::glue("https://github.com/IQAndreas/sample-images/blob/gh-pages/100-100-color/{11:20}.jpg?raw=true")
pts$img <- img
leaflet() %>%
addTiles() %>%
addCircleMarkers(data = pts, group = "pts") %>%
addPopupImages(pts$img, group = "pts")
Figured it out, with the help of Rich Pauloo! This is the code I ended up using the get local image files. It's a little clunky, but it worked out for me:
data_name <- readOGR("data/map_file.kml")
data_name2 <- data.frame(data_name)
pts <- st_as_sf(data.frame(data_name2),
coords = c("coords.x1", "coords.x2"), crs = 4326)
img <- c("images/picture_name.jpg") ##did this for every image I wanted to use, in the order
##that matched up with the data points I wanted them associated with.
pts$img <- img
leaflet() %>%
addTiles() %>%
addCircleMarkers(data = pts, group = "pts") %>%
addPopupImages(pts$img, group = "pts", width = 300)
Sorry if my conventions for writing out code are not quite right for the website. I just wanted to keep things generic and not include any of my file names or anything.

How to filter a raster layer and plot only the cells above a certain value in R using Leaflet?

I have a raster layer that contains 24-hour snow accumulations across the United States. The data can be pulled from here:
https://www.nohrsc.noaa.gov/snowfall_v2/data/202105/sfav2_CONUS_24h_2021052412.tif
I only want to plot the cells in the raster with values greater than or equal to 4 (inches) on a leaflet map. This is what my current map looks like:
https://i.stack.imgur.com/2Mi4r.png
I changed all values less than 4 to NA thinking that the raster cells wouldn't show up on the map. I want to remove all cells on the map that are greyed-out. The functions subset() and filter() do not work on raster layers. Any ideas? My code below for reference:
library(dplyr)
library(rgdal)
library(raster)
library(ncdf4)
library(leaflet)
library(leaflet.extras)
download.file(obsvSnow_Link, destfile = file.path(folderpath, 'observedSnow.tif'))
obsvSnow <- raster(file.path(folderpath, 'observedSnow.tif'))
names(obsvSnow) <- 'snowfall'
obsvSnow[obsvSnow < 4,] <- NA
colores <- c("transparent","#99CCFF","#3399FF","#0000FF","#FFE066", "#FF9900", "#E06666","#CC0000","#990033")
at <- c(4,8,seq(12,42,6),100)
cb <- colorBin(palette = colores, bins = at, domain = at)
mp <- leaflet(width = "100%",options = leafletOptions(zoomControl = FALSE)) %>%
addTiles() %>%
addRasterImage(x=obsvSnow$snowfall,
colors = cb,
opacity = 0.6) %>%
addLegend(title = 'Inches',
position='bottomright',
pal = cb, values = at) %>%
leaflet.extras::addSearchUSCensusBureau(options = searchOptions(autoCollapse=TRUE, minLength=10)) %>%
addScaleBar(position='bottomleft') %>%
addFullscreenControl()
mp

label for overlapping polygons in R leaflet

I need to label several overlapping polygons, but only the label of the biggest one is shown. However when I tested with some simulated data the labels were shown correctly. I compared the data in two cases carefully but cannot find the difference caused the problem.
Here is a minimal example of simulated overlapping polygons:
library(leaflet)
library(sp)
poly_a <- data.frame(lng = c(0, 0.5, 2, 3),
lat = c(0, 4, 4, 0))
poly_b <- data.frame(lng = c(1, 1.5, 1.8),
lat = c(2, 3, 2))
pgons = list(
Polygons(list(Polygon(poly_a)), ID="1"),
Polygons(list(Polygon(poly_b)), ID="2")
)
poly_dat <- data.frame(name = as.factor(c("a", "b")))
rownames(poly_dat) <- c("1", "2")
spgons = SpatialPolygons(pgons)
spgonsdf = SpatialPolygonsDataFrame(spgons, poly_dat, TRUE)
leaflet() %>% addPolygons(data = spgonsdf, label = ~name
# ,
# highlightOptions = highlightOptions(
# color = "red", weight = 2,bringToFront = TRUE)
)
It's working properly:
However it didn't work with my data.
https://github.com/rstudio/leaflet/files/1430888/Gabs.zip
You can drag the zip into this site and use the i button to see it's correctly labeled
library(rgdal)
# download Gabs.zip and extract files to Gabs folder
hr_shape_gabs <- readOGR(dsn = 'Gabs', layer = 'Gabs - OU anisotropic')
hr_shape_gabs_pro <- spTransform(hr_shape_gabs,
CRS("+proj=longlat +datum=WGS84 +no_defs"))
leaflet(hr_shape_gabs_pro) %>%
addTiles() %>%
addPolygons(weight = 1, label = ~name)
Only the biggest polygon label is shown:
The data in both case are SpatialPolygonsDataFrame, the data slot have proper polygon names.
Change the order of polygons in hr_shape_gabs: polygon in position 3 should be the smaller one.
library(leaflet)
library(sp)
library(rgdal)
hr_shape_gabs <- readOGR(dsn = 'Gabs - OU anisotropic.shp',
layer = 'Gabs - OU anisotropic')
# Change the position of the smaller and wider polygons
# Position 1 = wider polygon, position 3 = smaller polygon
pol3 <- hr_shape_gabs#polygons[[3]]
hr_shape_gabs#polygons[[3]] <- hr_shape_gabs#polygons[[1]]
hr_shape_gabs#polygons[[1]] <- pol3
hr_shape_gabs$name <- rev(hr_shape_gabs$name)
hr_shape_gabs_pro <- spTransform(hr_shape_gabs,
CRS("+proj=longlat +datum=WGS84 +no_defs"))
leaflet() %>%
addTiles() %>%
addPolygons(data= hr_shape_gabs_pro, weight = 1, label = ~name)
Here's a scalable solution in sf for many layers, based on this answer.
The idea is to order the polygons by decreasing size, such that the smallest polygons plot last.
library(sf)
library(dplyr)
# calculate area of spatial polygons sf object
poly_df$area <- st_area(poly_df)
poly_df <- arrange(poly_df, -area)
# view with labels in leaflet to see that small polygons plot on top
leaflet(poly_df) %>% addTiles() %>% addPolygons(label = ~id)
Apologies for the lack of reproducibility. This is more of a concept answer.

Resources