如何修复Leaflet自定义正负调色板反转后图例颜色错位问题
解决Leaflet自定义正负调色板+反转图例的刻度对齐问题
问题出在你反转调色板时,仅使用reverse=TRUE但未对应调整自定义颜色序列的顺序,导致正负颜色的汇合点偏离0值;同时labFormat里的额外排序操作进一步打乱了刻度与颜色的对应关系。
修改后的完整代码
library(shiny) library(leaflet) library(tidyverse) set.seed(999) # 读取国家地理数据 countries <- sf::st_read("https://rstudio.github.io/leaflet/json/countries.geojson") # 数据预处理 countries_mod <- countries %>% select(-gdp_md_est, -pop_est) %>% mutate( `2017` = runif(177, -140, 80), `2018` = runif(177, -20, 70), `2019` = runif(177, -288, 1400) ) %>% pivot_longer(cols = c(`2017`:`2019`)) ui <- fluidPage( selectInput( inputId = "year_select", label = "年份", choices = c("2017", "2018", "2019") ), leafletOutput("plot", height = "500px") ) server <- function(input, output) { # 按年份过滤数据 Filtered_dat <- reactive({ countries_mod %>% filter(name == input$year_select) }) output$plot <- renderLeaflet({ leaflet(countries) %>% addTiles() }) observeEvent(Filtered_dat(), { # 生成负数值颜色(从深红到浅红) colors_negative <- colorRampPalette(c("#fe0000", "#fFc7c7"))(abs(min(Filtered_dat()$value))) # 生成正数值颜色(从浅绿到深绿) colors_positive <- colorRampPalette(c("#d0f0b7", "#6dfe00"))(max(Filtered_dat()$value)) # 原调色板(负→0→正) pal <- colorNumeric(c(colors_negative, colors_positive), domain = Filtered_dat()$value) # 反转图例用的调色板:手动构建正→0→负的颜色序列,配合domain反转实现降序图例 rev_color_sequence <- c(rev(colors_positive), rev(colors_negative)) rev_pal <- colorNumeric(rev_color_sequence, domain = Filtered_dat()$value, reverse = TRUE) leafletProxy("plot") %>% setView(0, 0, 1) %>% clearShapes() %>% addPolygons( data = Filtered_dat(), label = ~value, fillColor = ~pal(value), fillOpacity = 1, color = "#FEFEFE", weight = 1 ) %>% clearControls() %>% addLegend( pal = rev_pal, values = Filtered_dat()$value # 移除多余排序,reverse=TRUE已自动实现降序刻度 ) }) } shinyApp(ui = ui, server = server)
关键改动说明
重构反转调色板的颜色序列
原代码直接反转整个颜色序列会破坏正负值在0点的汇合逻辑,修改后我们手动组合反转后的正负颜色:将正数值的「浅绿→深绿」反转为「深绿→浅绿」,负数值的「深红→浅红」反转为「浅红→深红」,最终形成「深绿→浅绿→浅红→深红」的序列,完美对应从最大值到最小值的颜色过渡,0点的颜色汇合逻辑得以保留。移除多余的
labFormat排序colorNumeric的reverse=TRUE参数已经会让图例刻度按降序排列,额外的排序操作会导致刻度与颜色错位,直接移除即可。简化代码调用
将~pal(Filtered_dat()[['value']])简化为~pal(value),代码更简洁且逻辑一致。
内容的提问来源于stack exchange,提问作者anorlondo
相关产品推荐
相关产品推荐

