如何让R的plotly堆叠条形图中不同样本组显示对应图案?
问题描述
我有一个data.frame,希望用R的plotly绘制堆叠条形图:
data.df <- data.frame(group = c(rep("g1",6),rep("g2",6),rep("g3",6)), sample = rep(c(paste0("f", 1:3), paste0("m", 1:3)), 3), f = rep(100/6, 6))
其中每个data.df$group对应一个条形,data.df$sample是每个条形的堆叠层(各层颜色不同),我希望f开头和m开头的两组sample分别显示不同图案。
我定义了包含颜色和图案的data.frame:
colors.df <- data.frame(sample = c(c(paste0("f", 1:3)), c(paste0("m", 1:3))), color = rep(c("#FFC0CB", "#FFFF00", "#00FFFF"),2), shape = c(rep("stripe", 3),rep("cross", 3)))
以下是我尝试的plotly代码:
library(plotly) plot_ly(x = data.df$group, y = data.df$f, name = data.df$sample, color = data.df$sample, type = 'bar', colors = colors.df$color, marker = list(pattern = list(shape = colors.df$chape))) %>% layout(xaxis = list(showticklabels = F), yaxis = list(title = "%", zeroline = F), barmode = 'stack', orientation = 'v')
但该代码忽略了marker参数,图案未显示。请问如何让两组sample显示不同的图案?
解决方案
你的代码存在两个核心问题导致图案不显示:
- 拼写错误:
colors.df$chape应为colors.df$shape - Plotly无法通过全局设置
marker.pattern.shape直接按分组映射图案,需要通过分组映射trace样式来实现。
方案一:合并数据后逐trace设置样式
先将数据与颜色、图案配置合并,再为每个sample分组的trace单独设置样式:
library(plotly) library(dplyr) # 合并数据,匹配每个sample对应的颜色和图案 merged_df <- data.df %>% left_join(colors.df, by = "sample") plot_ly(merged_df, x = ~group, y = ~f, split = ~sample, type = 'bar', barmode = 'stack') %>% # 遍历每个trace设置样式 lapply(function(trace) { sample_info <- merged_df %>% filter(sample == trace$name) %>% slice(1) trace$marker$color <- sample_info$color trace$marker$pattern$shape <- sample_info$shape trace$marker$pattern$size <- 10 # 调整图案大小 trace$marker$pattern$fillratio <- 0.5 # 调整图案填充比例 return(trace) }) %>% layout(xaxis = list(showticklabels = F), yaxis = list(title = "%", zeroline = F), orientation = 'v')
方案二:直接通过命名向量映射样式
利用命名向量将sample与对应的颜色、图案绑定,直接在plot_ly中映射:
library(plotly) # 创建颜色和图案的命名向量 color_map <- setNames(colors.df$color, colors.df$sample) shape_map <- setNames(colors.df$shape, colors.df$sample) plot_ly(data.df, x = ~group, y = ~f, color = ~sample, type = 'bar', barmode = 'stack', colors = color_map, marker = list( pattern = list( shape = ~shape_map[sample], size = 8, fillratio = 0.4 ) )) %>% layout(xaxis = list(showticklabels = F), yaxis = list(title = "%", zeroline = F), orientation = 'v')
关键注意事项
- 必须用命名向量实现sample与样式的精准匹配,避免样式错乱
marker.pattern的size和fillratio参数可根据需求调整,优化图案显示效果- 优先检查变量名拼写,笔误是这类问题的常见诱因
内容的提问来源于stack exchange,提问作者user1701545
相关产品推荐
相关产品推荐

