R语言HighCharter堆叠柱状图的顺序与颜色自定义问题
HighCharter堆叠柱状图:调整堆叠顺序与颜色问题解决
问题背景
在HighCharter中制作堆叠柱状图时,遇到以下问题:
- 尝试通过
hc_xAxis()定义分类导致X轴日期格式失效,堆叠顺序未按期望改变; - 自定义颜色未生效,颜色按字母顺序映射;
- 期望堆叠顺序(从下到上):TL > WB > PB > UB > NACx > ACx。
原始数据框
df <- structure(list(Week = structure(c(19478, 19478, 19478, 19478, 19478, 19478, 19478, 19485, 19485, 19485, 19485, 19485, 19485, 19485, 19492, 19492, 19492, 19492, 19492, 19492, 19492, 19499, 19499, 19499, 19499, 19499, 19499, 19499, 19506, 19506, 19506, 19506, 19506, 19506, 19506, 19513, 19513, 19513, 19513, 19513, 19513, 19513), class = "Date"), Status = c("ACx", "NACx", "PB", "Plan", "TL", "UB", "WB", "ACx", "NACx", "PB", "Plan", "TL", "UB", "WB", "ACx", "NACx", "PB", "Plan", "TL", "UB", "WB", "ACx", "NACx", "PB", "Plan", "TL", "UB", "WB", "ACx", "NACx", "PB", "Plan", "TL", "UB", "WB", "ACx", "NACx", "PB", "Plan", "TL", "UB", "WB"), Units = c(0, 7.13, 46.49, 298.03, 48.11, 20.25, 166.12, 0, 12.87, 67, 298.03, 47, 38, 126.26, 0, 9, 66.27, 328.37, 53.25, 90.25, 98.62, 0, 9.25, 53.13, 355.89, 53.11, 180.5, 45.13, 4, 2.88, 0, 269.55, 6, 169.5, 0, 0, 0, 0, 355.89, 0, 0, 0)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -42L), groups = structure(list( Week = structure(c(19478, 19485, 19492, 19499, 19506, 19513 ), class = "Date"), .rows = structure(list(1:7, 8:14, 15:21, 22:28, 29:35, 36:42), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -6L), .drop = TRUE))
原始绘图代码
highchart() %>% hc_add_series(subset(df, Status == "Plan"), "column", grouping = FALSE, stack = "Plan", color = 'rgba(255, 255, 255, 0)', borderColor = "black", hcaes(x = Week, y = round(Units, digits = 1), group = Status)) %>% hc_add_series(subset(df, Status != "Plan"), type = 'column', grouping = FALSE, stack = "Activity", borderColor = "black", color = cols, hcaes(y = Units, group=Status, x = Week)) %>% hc_chart(plotBackgroundColor = "#F5F5F5") %>% hc_plotOptions(series = list(stacking = "normal")) %>% hc_xAxis(dateTimeLabelFormats = list(week = '%d-%b'), type = "datetime", title = list(text = "Week Commencing"), gridLineWidth = 1, tickInterval = 604800000) %>% hc_yAxis(title = list(text = "Activity)")) cols <- c("ACx" = "#311432", "NACx" = "#a1045a", "WB" = "forestgreen", "TL" = "#D3D3D3", "PB" = "goldenrod", "UB" = "#bc544b")
解决方案
步骤1:预处理数据,控制系列顺序
将Status转为因子,指定期望的堆叠顺序(从下到上),同时确保数据按该顺序排序:
# 定义堆叠顺序(从下到上) status_order <- c("TL", "WB", "PB", "UB", "NACx", "ACx", "Plan") # 转换因子并排序数据 df <- df %>% ungroup() %>% mutate(Status = factor(Status, levels = status_order)) %>% arrange(Week, Status) # 对应因子顺序的颜色向量(顺序需与status_order完全匹配) cols <- c( "TL" = "#D3D3D3", "WB" = "forestgreen", "PB" = "goldenrod", "UB" = "#bc544b", "NACx" = "#a1045a", "ACx" = "#311432", "Plan" = 'rgba(255, 255, 255, 0)' )
步骤2:调整绘图代码
通过因子水平控制系列生成顺序,使用hc_colors()映射自定义颜色,同时保留日期轴格式:
highchart() %>% # 一次性添加所有数据,利用因子水平自动生成正确顺序的系列 hc_add_series(df, type = "column", hcaes(x = Week, y = Units, group = Status), borderColor = "black") %>% hc_chart(plotBackgroundColor = "#F5F5F5") %>% hc_plotOptions( series = list( stacking = "normal", # 可选:禁止Plan系列的图例点击,避免打乱堆叠结构 events = list(legendItemClick = function() return(FALSE)) ), column = list(states = list(inactive = list(opacity = 1))) # 保持Plan系列始终可见 ) %>% hc_xAxis( type = "datetime", dateTimeLabelFormats = list(week = '%d-%b'), title = list(text = "Week Commencing"), gridLineWidth = 1, tickInterval = 604800000 # 7天对应的毫秒数 ) %>% hc_yAxis(title = list(text = "Activity")) %>% # 按因子顺序设置颜色 hc_colors(unname(cols)) %>% # 为Plan系列单独设置堆叠组,避免与其他系列堆叠 hc_series( lapply(.data$x$series, function(s) { s$stack <- ifelse(s$name == "Plan", "Plan", "Activity") s }) )
关键说明
- 堆叠顺序控制:HighCharter按因子水平的顺序生成系列,堆叠时第一个因子水平在最下方,完全匹配期望的顺序;
- 颜色映射:
hc_colors()接收无命名的颜色向量,顺序必须与因子水平一致,确保每个系列对应正确颜色; - 堆叠组分离:通过
hc_series()遍历系列,将Plan分配到单独堆叠组,保持其作为边框的显示效果; - 日期轴保留:保持
type="datetime"参数,避免日期格式失效。
内容的提问来源于stack exchange,提问作者rollingstone
相关产品推荐
相关产品推荐

