0

I am using the script below to make to make interactive leaflet map. However, the contours have sharp changes and are not smooth and round. How can I edit this code to achieve that?

The data and code is from this link: https://adelieresources.com/2022/10/making-contour-maps-in-r/

    Sta_den <- eks::st_kde(df) # calculate density
    contours <- eks::st_get_contour(Sta_den, cont=c(20,40,60,80)) %>% 
      mutate(value=as.numeric(levels(contlabel)))
    pal <- colorBin("YlOrRd", contours$contlabel, bins = c(20,40,60,80), reverse = TRUE)
    
    pal_fun <- leaflet::colorQuantile("YlOrRd", NULL, n = 4)
    
    p_popup <- paste("Density", as.numeric(levels(contours$contlabel)), "%")
    
    leaflet::leaflet(contours) %>% 
      leaflet::addTiles() %>% # OpenStreetMap by default
      leaflet::addPolygons(fillColor = ~pal_fun(as.numeric(contlabel)),
                           popup = p_popup, weight=2)%>% 
      leaflet::addLegend(pal = pal, values = ~contlabel, group = "circles", position = "bottomleft",title="Density quantile")
1
  • 2
    Can you demonstrate the problem with an image, or at least include some reproducible data that we could use to see what you mean? Commented Jan 11 at 14:31

1 Answer 1

1

The problem seems to be that you have a lower-than-desired resolution of 2D density. This can be controlled with the gridsize argument of eks::st_kde.

For example, if we only calculate density over a 10 by 10 grid, the contours look horribly jagged:

Sta_den <- eks::st_kde(df, gridsize = c(10, 10))

enter image description here

If we set the grid to be 500 x 500, then the calculation takes a lot longer, but the end result is perfect:

Sta_den <- eks::st_kde(df, gridsize = c(500, 500))

enter image description here

The default value is somewhere in between.

Other things you can try is reducing smoothFactor inside leaflet::addPolygons, and actually smoothing the contour lines themselves using smoothr::smooth

Sta_den <- eks::st_kde(df, gridsize = c(100, 100))
contours <- eks::st_get_contour(Sta_den, cont = c(20,40,60,80)) %>% 
  mutate(value=as.numeric(levels(contlabel)))
pal <- colorBin("YlOrRd", contours$contlabel, bins = c(20,40,60,80), 
                reverse = TRUE)

pal_fun <- leaflet::colorQuantile("YlOrRd", NULL, n = 4)

p_popup <- paste("Density", as.numeric(levels(contours$contlabel)), "%")

leaflet::leaflet(smoothr::smooth(contours)) %>% 
  leaflet::addTiles() %>% # OpenStreetMap by default
  leaflet::addPolygons(fillColor = ~pal_fun(as.numeric(contlabel)),
                       popup = p_popup, weight=2, smoothFactor = 0.5) %>% 
  leaflet::addLegend(pal = pal, values = ~contlabel, group = "circles", 
                     position = "bottomleft",title="Density quantile")

enter image description here

Not the answer you're looking for? Browse other questions tagged or ask your own question.