如何在Plotly箱线图中同时设置填充色与边框色属性
用Plotly原生函数实现分层分组箱线图(自定义边框色+填充色)
问题描述
我有一组层级化数据,需要生成分组箱线图,要求按group_a设置填充色,按group_c设置边框色。这个需求用ggplot2很容易实现(示例如下),但无法直接用Plotly原生函数实现。另外因为大数据集下ggplotly()性能太差,所以不考虑这种转换方式。
额外需求:如何在Plotly方案中手动指定group_c的边框颜色,实现类似ggplot2中scale_colour_manual()的功能。
数据准备
注:原代码中length(lot_ids)为笔误,已修正为length(group_b)
group_a <- 900:904 group_b <- paste0(rep(group_a, each = 3), '_', rep(c('01', '02', '03'), times = length(group_a))) group_c <- rep(c("A", "B"), times = length(group_b)) # 修正原代码中的变量错误 group_date <- seq.Date(from = as.Date("2025-01-01"), by = "day", length.out = length(group_b)) group_date <- rep(group_date, each = 3) x <- rep(runif(14), times = length(group_a) * 3 * 2) # 创建数据框 df <- data.frame( group_a = rep(group_a, each = 3 * 2 * 14), group_b = rep(group_b, each = 14 * 2), group_date = rep(group_date, each = 2 * 14), group_c = group_c, x = x )
ggplot2参考实现
library(ggplot2) library(dplyr) df %>% ggplot(aes( x = group_date, y = x, group = interaction(group_c, group_b), fill = factor(group_a), colour = group_c )) + geom_boxplot()

Plotly原生实现方案
1. 自定义颜色映射
先手动定义group_c的边框色(对应ggplot2的scale_colour_manual),以及group_a的填充色:
library(plotly) # 手动指定group_c的边框颜色 group_c_colors <- c("A" = "#1f77b4", "B" = "#ff7f0e") # 手动指定group_a的填充色(也可使用默认色阶) group_a_colors <- c("900" = "#aec7e8", "901" = "#ffbb78", "902" = "#98df8a", "903" = "#ff9896", "904" = "#c5b0d5")
2. 处理分组与颜色关联
为数据框添加交互分组列,并绑定对应的填充色和边框色:
df <- df %>% mutate( # 创建与ggplot一致的交互分组 plot_group = interaction(group_c, group_b), # 匹配group_a对应的填充色 fill_color = group_a_colors[as.character(group_a)], # 匹配group_c对应的边框色 line_color = group_c_colors[group_c] )
3. 绘制分组箱线图
用Plotly原生函数实现分组效果,同时应用自定义颜色:
plot_ly(df, x = ~group_date, y = ~x, split = ~plot_group, type = "box", fillcolor = ~fill_color, line = list(color = ~line_color), showlegend = FALSE) %>% layout( xaxis = list(title = "日期"), yaxis = list(title = "x值"), boxmode = "group" # 开启分组模式,让同日期的箱线图并排显示 )
关键说明
split = ~plot_group:实现和ggplot中group = interaction(group_c, group_b)完全一致的分组逻辑fillcolor = ~fill_color:将填充色与group_a绑定line = list(color = ~line_color):将边框色与自定义的group_c颜色映射绑定boxmode = "group":确保同一x轴位置的多个箱线图并排,还原ggplot的分组效果
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

