I am trying to create a leaflet map with lines joining a list of stops. I used polylines on a leaflet map to do so.
I am now trying to color the lines by the variable (weight).
I tried creating color values on a defined gradient but it doesn't seem to work. I tried creating a gradient scale based on the weight variable and assigning that to the lines, but I think I'm missing something
gradientFunction <- colorRampPalette(c("red", "yellow"))
colorGradient <- gradientFunction(nrow(x))
x$color = colorGradient
x %>%
mutate(Lat = as.numeric(Lat),
Long = as.numeric(Long)) %>%
arrange(sequence) %>%
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addPolylines(
lng = ~Long,
lat = ~Lat,
weight = 3,
opacity = 3,
color = ~color) %>%
addCircleMarkers(
lng = ~Long,
lat = ~Lat,
radius = 2,
fillColor = "Black",
fillOpacity = 1,
stroke = F)
Data:
structure(list(Lat = c("1.28210155945393", "1.28329993019059",
"1.28394108576437", "1.28475980959972", "1.284977", "1.28572048365401",
"1.28583847140468", "1.28593135445772", "1.28623157720487", "1.28723833324362",
"1.28736808047078", "1.29078162052352", "1.293615", "1.29395444170081",
"1.2950426189642", "1.295962316986", "1.29618544092334", "1.29796011528522",
"1.29811014243867", "1.29831153783592", "1.29986928715834", "1.30027569326586",
"1.30044251755834", "1.30070547633658", "1.302127", "1.30252834773643",
"1.304086", "1.30425500081318", "1.30496423786628", "1.30528972611328",
"1.30566306799291", "1.30595638898755", "1.30674381370885", "1.30711835522323",
"1.3071917122941", "1.30726086825664", "1.30787614366531", "1.30821308595952",
"1.30837865741776", "1.30851455788092", "1.30862937328019", "1.30938972202558",
"1.30943460005849", "1.31135799079971", "1.31250502315071", "1.31295810131062",
"1.31390444400831", "1.31656999665769", "1.31875790465263", "1.32132832560695",
"1.32453874317344"), Long = c("103.81722480263163", "103.81547665017668",
"103.81783962251122", "103.83405671725487", "103.821011", "103.8285292287095",
"103.83238179897589", "103.82668969231534", "103.83496162445665",
"103.82259298997768", "103.82346004890803", "103.83440916705554",
"103.832759", "103.85139096636622", "103.83205533028763", "103.85795174896221",
"103.84958029974611", "103.83053183555204", "103.84780636909545",
"103.8452569595532", "103.84093746088925", "103.83877618459663",
"103.83623804216019", "103.86336013257065", "103.829875", "103.83239784275958",
"103.907533", "103.9123223933556", "103.91493558885941", "103.90534997934479",
"103.9110051545323", "103.91698861102066", "103.875264139574",
"103.87989373246151", "103.91764721757994", "103.88490711001795",
"103.92111718654822", "103.88850877408412", "103.90304313394574",
"103.92471047692146", "103.8906311270188", "103.89936888898059",
"103.8966101212743", "103.92481225868325", "103.9250247698478",
"103.92790605020116", "103.93171138898548", "103.93334015990408",
"103.93158674239623", "103.92782177344944", "103.92903818515839"
), Weight = c(0, 79, 124, 276, 333, 332, 341, 500, 287, 458,
462, 322, 364, 409, 374, 475, 401, 512, 390, 448, 396, 391, 370,
539, 493, 453, 668, 558, 429, 593, 581, 274, 558, 562, 230, 575,
225, 593, 652, 214, 939, 818, 1054, 210, 219, 231, 266, 293,
285, 281, 235), sequence = c(51, 50, 49, 42, 48, 44, 43, 45,
41, 47, 46, 40, 39, 28, 38, 27, 29, 37, 30, 31, 32, 33, 34, 26,
36, 35, 16, 14, 13, 17, 15, 12, 25, 24, 11, 23, 10, 22, 18, 9,
21, 19, 20, 8, 7, 6, 5, 4, 3, 2, 1)), row.names = c(NA, -51L), class = c("tbl_df",
"tbl", "data.frame"))
To color different segments you'd also need to create those segments first, one possible approach with sf
as an example.
The resulting x_sf
has 2 geometry columns line_seg
& points
, default being line_seg
. And when passing x_sf
to leaflet
or using it for data
argument,line_seg
will be used for plotting. To point addCircleMarkers()
to point column, data
argument becomes x_sf$points
.
Alternatively you could opt for leaflet plugins, https://github.com/Oliv/leaflet-polycolor for example.
library(leaflet)
library(dplyr)
library(sf)
x_sf <- st_as_sf(x, coords = c("Long", "Lat"), crs = "WGS84") %>%
arrange(`sequence`) %>%
mutate(geom_lead = lead(geometry)) %>%
slice(-n()) %>%
rowwise() %>%
mutate(line_seg = st_union(geometry, geom_lead) %>% st_cast("LINESTRING")) %>%
ungroup() %>%
st_set_geometry("line_seg") %>%
select(Weight, sequence, points = geometry)
gradientFunction <- colorRampPalette(c("red", "yellow"))
colorGradient <- gradientFunction(nrow(x_sf))
x_sf$color = colorGradient
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addPolylines(
data = x_sf,
weight = 3,
opacity = 3,
color = ~color) %>%
addCircleMarkers(
data = x_sf$points,
radius = 2,
fillColor = "Black",
fillOpacity = 1,
stroke = F)
Resulting x_sf
object:
x_sf
#> Simple feature collection with 50 features and 3 fields
#> Active geometry column: line_seg
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: 103.8155 ymin: 1.282102 xmax: 103.9333 ymax: 1.324539
#> Geodetic CRS: WGS 84
#> # A tibble: 50 × 5
#> Weight sequence points line_seg color
#> * <dbl> <dbl> <POINT [°]> <LINESTRING [°]> <chr>
#> 1 235 1 (103.929 1.324539) (103.9278 1.321328, 103.929 1.3245… #FF0…
#> 2 281 2 (103.9278 1.321328) (103.9316 1.318758, 103.9278 1.321… #FF0…
#> 3 285 3 (103.9316 1.318758) (103.9316 1.318758, 103.9333 1.316… #FF0…
#> 4 293 4 (103.9333 1.31657) (103.9333 1.31657, 103.9317 1.3139… #FF0…
#> 5 266 5 (103.9317 1.313904) (103.9279 1.312958, 103.9317 1.313… #FF1…
#> 6 231 6 (103.9279 1.312958) (103.925 1.312505, 103.9279 1.3129… #FF1…
#> 7 219 7 (103.925 1.312505) (103.9248 1.311358, 103.925 1.3125… #FF1…
#> 8 210 8 (103.9248 1.311358) (103.9247 1.308515, 103.9248 1.311… #FF2…
#> 9 214 9 (103.9247 1.308515) (103.9211 1.307876, 103.9247 1.308… #FF2…
#> 10 225 10 (103.9211 1.307876) (103.9176 1.307192, 103.9211 1.307… #FF2…
#> # … with 40 more rows
Created on 2023-03-01 with reprex v2.0.2