You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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显示不同的图案?

解决方案

你的代码存在两个核心问题导致图案不显示:

  1. 拼写错误:colors.df$chape应为colors.df$shape
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 07:30:17