如何为两个带时间滑块的Plotly sf分面地图设置共用色条
解决方案:配对地图共用贯穿式色条并支持自定义范围
需求说明
我当前有一组配对显示的地图,带有共用的时间滑块,希望为两个子地图设置一个贯穿整个显示高度的共用色条(替代当前各占一半高度的两个色条a和b),同时需要实现可自定义色条范围的功能。
实现代码
library(sf) library(plotly) library(tidyr) library(dplyr) library(glue) # 加载示例数据 fname <- system.file("shape/nc.shp", package="sf") nc <- st_read(fname) years <- 2000:2010 nc_names <- nc[, "NAME"] %>% st_drop_geometry() set.seed(12) fake_dta <- expand_grid(nc_names, year = years) %>% mutate(a = runif(n()), b = runif(n()) ) %>% mutate( text_a = glue("In {NAME} in {year}, a was {round(a, 2)}"), text_b = glue("In {NAME} in {year}, b was {round(b, 2)}") ) nc2 <- nc %>% left_join(fake_dta) # -------------------------- # 自定义色条范围(按需修改) color_min <- 0 color_max <- 1 # -------------------------- # 配置共用色条:贯穿整个高度,放在子图右侧 shared_colorbar <- list( title = "数值", len = 1, # 色条高度占满绘图区 y = 0.5, # 垂直居中 yanchor = "middle", x = 1.05, # 位置偏移到子图外侧 xanchor = "left", tickvals = seq(color_min, color_max, by = 0.2), # 自定义刻度 ticktext = seq(color_min, color_max, by = 0.2) ) # 绘制地图A:隐藏自身色条,使用统一范围 map_a <- plot_ly(nc2) %>% add_sf( split = ~NAME, color = ~a, frame = ~year, stroke = I("black"), text = ~text_a, hoveron = "fills", hoverinfo = "text", showlegend = FALSE, type = "scatter", mode = "lines", colors = "Viridis", # 隐藏默认色条 colorbar = list(x = -100, len = 0), # 绑定统一的颜色范围 zmin = color_min, zmax = color_max ) %>% add_annotations( text = "A", x = 0.5, y = 1, yref = "paper", xref = "paper", yanchor = "bottom", valign = "middle", align = "center", showarrow = FALSE, font = list(size = 15) ) %>% layout( showlegend = FALSE, shapes = list( type = "rect", x0 = 0, x1 = 1, xref = "paper", y0 = 0, y1 = 16, yanchor = 1, yref = "paper", ysizemode = "pixel", fillcolor = toRGB("gray80"), line = list(color = "transparent") ) ) # 绘制地图B:挂载共用色条,使用统一范围 map_b <- plot_ly(nc2) %>% add_sf( split = ~NAME, color = ~b, frame = ~year, stroke = I("black"), text = ~text_b, hoveron = "fills", hoverinfo = "text", showlegend = FALSE, type = "scatter", mode = "lines", colors = "Viridis", # 应用共用色条配置 colorbar = shared_colorbar, # 绑定统一的颜色范围 zmin = color_min, zmax = color_max ) %>% add_annotations( text = "B", x = 0.5, y = 1, yref = "paper", xref = "paper", yanchor = "bottom", valign = "middle", align = "center", showarrow = FALSE, font = list(size = 15) ) %>% layout( showlegend = FALSE, shapes = list( type = "rect", x0 = 0, x1 = 1, xref = "paper", y0 = 0, y1 = 16, yanchor = 1, yref = "paper", ysizemode = "pixel", fillcolor = toRGB("gray80"), line = list(color = "transparent") ) ) # 组合子图,保留共用时间滑块 subplot(map_a, map_b, nrows = 1) %>% layout( updatemenus = list(list( type = "buttons", showactive = FALSE, buttons = list( list(label = "播放", method = "animate", args = list(NULL, list(frame = list(duration = 500, redraw = TRUE), transition = list(duration = 0)))), list(label = "暂停", method = "animate", args = list(list(frame = list(duration = 0, redraw = FALSE)), list(mode = "immediate", transition = list(duration = 0)))) ) )) )
关键修改说明
- 统一颜色映射范围:通过
zmin和zmax强制两个地图使用相同的颜色对应区间,保证数据可视化的一致性。 - 隐藏冗余色条:将左侧地图的默认色条偏移到可视区域外,避免重复显示。
- 配置贯穿式共用色条:设置
len=1让色条高度匹配整个绘图区,调整位置参数使其不遮挡地图内容。 - 自定义色条范围:直接修改
color_min和color_max即可调整色条的数值区间,同时支持自定义刻度。
内容的提问来源于stack exchange,提问作者JonMinton
相关产品推荐
相关产品推荐

