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

如何在Plotly中不依赖ggplotly实现按两组分组的叠加条形图(复刻ggplot效果)

如何在Plotly中不依赖ggplotly实现按两组分组的叠加条形图(复刻ggplot效果)

嘿,我懂你想要完全用Plotly复刻出ggplot做的那种分组叠加条形图,而且不想靠ggplotly转译的心情!那咱们一步步来实现,先从数据预处理开始,再到Plotly的可视化代码~

第一步:预处理数据(先聚合再转宽格式)

首先得把原始的长格式数据转换成适合Plotly做叠加条形的结构,就像你提到的那样,先按三个分组字段统计数量,再转成宽格式:

library(data.table)
library(plotly)

# 生成原始数据(和你提供的一致)
n = 7200
n1 = 4/3*n
n2 = 2*n
dt = data.table(x = sample(rep(c("0-20", "21-40", "41-60", "61-80"), n)),
                group1 = sample(rep(c("A", "B", "C"), n1)),
                group2 = sample(rep(c(0, 1), n2))
)
setorder(dt, x, group1, group2)
dt[, x := factor(x)]
dt[, group1 := factor(group1)]
dt[, group2 := factor(group2)]

# 聚合统计数量
dt_agg = dt[, .N, by = .(x, group1, group2)]
# 转成宽格式,方便Plotly处理叠加
dt_wide = dcast(dt_agg, x + group1 ~ group2, value.var = "N")
# 把group1按逆序排列,对应ggplot里的fct_rev
dt_wide[, group1 := forcats::fct_rev(group1)]

第二步:用Plotly实现复刻效果

接下来我们用Plotly的subplot来模拟ggplot的facet_grid行分面效果,每个group1类别对应一个子图,然后在每个子图里做group2的叠加条形,同时调整样式匹配你的ggplot效果:

# 先定义颜色,和你ggplot里的一致
fill_colors = c("#9c868b", "#038073")
names(fill_colors) = c("0", "1")

# 按group1拆分数据,生成每个子图的trace
group_list = unique(dt_wide$group1)
plot_list = lapply(group_list, function(g) {
  sub_data = dt_wide[group1 == g]
  # 第一个group2的条形(底层)
  trace0 = bar(
    x = sub_data$N,
    y = sub_data$x,
    orientation = "h",
    marker = list(color = fill_colors["0"]),
    showlegend = FALSE
  )
  # 第二个group2的条形(叠加层)
  trace1 = bar(
    x = sub_data$`1`,
    y = sub_data$x,
    orientation = "h",
    marker = list(color = fill_colors["1"]),
    showlegend = FALSE
  )
  # 组合子图,设置标题为group1的类别,放在左侧
  subplot(trace0, trace1, shareY = TRUE, shareX = FALSE, titleX = FALSE, titleY = TRUE) %>%
    layout(
      title = list(text = g, x = -0.1, y = 0.5, xanchor = "right", yanchor = "middle"),
      yaxis = list(title = "", categoryorder = "array", categoryarray = sub_data$x),
      xaxis = list(title = "", position = 1) # x轴(对应ggplot的y轴)放在右侧
    )
})

# 把所有子图垂直拼接,调整整体布局
final_plot = subplot(plot_list, nrows = length(group_list), shareX = TRUE, shareY = TRUE, margin = 0.05) %>%
  layout(
    barmode = "stack", # 设置叠加模式
    xaxis = list(title = "Count"),
    showlegend = FALSE,
    margin = list(l = 100) # 给左侧的group1标题留足够空间
  )

# 查看最终图
final_plot

这样做出来的效果就和你用ggplot生成的几乎一致了:横向的叠加条形、group1作为垂直分面(每个类别单独一块)、数值轴在右侧、没有图例,颜色也和你指定的完全匹配。

备注:内容来源于stack exchange,提问作者nimliug

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 13:03:12