R Leaflet - use date or character legend labels with colorNumeric() palette

后端 未结 1 1439
清酒与你
清酒与你 2020-12-18 06:19

I have a dataset with lat/lon and a timestamp. I want the color of the markers to show time with a continous palette. I am using colorNumeric() with julian date

相关标签:
1条回答
  • 2020-12-18 06:54

    From the leaflet page on legends:

    You can also conveniently customize the label appearance by passing labFormat=labelFormat(). labelFormat() has parameters that customize the separator between ranges, the number of digits to render, and prefix/suffix for each label. If your label formatting needs extend beyond what labelFormat() can provide, you can also use a custom function as the labFormat argument; see the Details section in ?addLegend for a description.

    Therefore, we can modify the source code for the labelFormat function to include a custom function to convert dates

    myLabelFormat = function(
      prefix = '', suffix = '', between = ' – ', digits = 3, big.mark = ',',
      transform = identity, dates = FALSE   ## new 'dates' argument
    ) {
    
      formatNum = function(x) {
        format(
          round(transform(x), digits), trim = TRUE, scientific = FALSE,
          big.mark = big.mark
        )
      }
      ## added 'formatDate' function
      formatDate = function(x) {
        d = as.Date(x, origin="1970-01-01")
      }
    
      function(type, ...) {
        switch(
          type,
          numeric = (function(cuts) {
            if(dates){   
              ## will format numbers into dates if dates == TRUE
              paste0(formatDate(cuts))
            }else{
              paste0(prefix, formatNum(cuts), suffix)
            }
          })(...),
          bin = (function(cuts) {
            n = length(cuts)
            paste0(prefix, formatNum(cuts[-n]), between, formatNum(cuts[-1]), suffix)
          })(...),
          quantile = (function(cuts, p) {
            n = length(cuts)
            p = paste0(round(p * 100), '%')
            cuts = paste0(formatNum(cuts[-n]), between, formatNum(cuts[-1]))
            # mouse over the legend labels to see the values (quantiles)
            paste0(
              '<span title="', cuts, '">', prefix, p[-n], between, p[-1], suffix,
              '</span>'
            )
          })(...),
          factor = (function(cuts) {
            paste0(prefix, as.character(transform(cuts)), suffix)
          })(...)
        )
      }
    }
    

    Which, as @Nice points out can be shortened to

    myLabelFormat = function(...,dates=FALSE){ 
      if(dates){ 
        function(type = "numeric", cuts){ 
          as.Date(cuts, origin="1970-01-01")
        } 
      }else{
        labelFormat(...)
      }
    }
    

    With this new function we can call it as normal

    data = structure(list(timestamp = structure(c(1434056453, 1434148216, 1434153635, 1434245436, 1434358840, 
                                                  1434364288, 1434369611, 1434461435, 1434466830, 1434558725), class = c("POSIXct", "POSIXt"), tzone = ""), 
                          lon = c(-119.8777, -119.9614, -119.8769, -119.8775, -120.2283, 
                                  -120.2285, -119.8429, -120.0954, -120.3957, -120.4421), 
                          lat = c(34.4041,34.376, 34.4061, 34.4021, 34.4696, 
                                  34.4697, 34.1909, 34.4328, 34.4554, 34.4456), 
                          ID = as.factor(c("Z11","Z05","Z01", "Z04", "Z11", "Z04","Z01","Z05","Z05","Z11"))), 
                     .Names = c("timestamp", "lon", "lat", "ID"),
                     row.names = c(1:10), 
                     class = "data.frame")
    
    data$julian <- as.numeric(as.Date(data$timestamp))
    
    
    library(leaflet)
    
    pal = colorNumeric(  palette = rainbow(7), domain = data$julian) 
    
    m = leaflet(data)
    m %>% addTiles() %>% 
      addCircles(~lon, ~lat, color = ~pal(julian)) %>% 
      addLegend("bottomright", pal = pal, values = ~julian, 
                 title = "Time", opacity = 1, 
                 labFormat = myLabelFormat(dates=TRUE))
    

    0 讨论(0)
提交回复
热议问题