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

如何在Plotly水平堆叠条形图中嵌入饼图并匹配颜色?

问题描述

我用R语言的plotly包制作了水平堆叠条形图(右侧预留空间为有意设置):

library(dplyr)
library(plotly)
library(tidyr)

d <- tibble(cat = LETTERS[1:3],
            val = c(25, 10, 30),
            total = 40)

(bars <- d %>%
  mutate(remaining = total - val) %>%
  pivot_longer(cols = c(val, remaining)) %>% 
  plot_ly(x = ~ value, y =  ~ cat, 
          type = "bar", 
          orientation = 'h', color = ~ name, 
          colors = c("#440154FF", "#FDE725FF")) %>%
  layout(xaxis = list(title = NA, range= c(0, 60)),
         yaxis = list(title = NA),
         showlegend = FALSE,
         barmode = "stack"))

现在希望在x == 50的对应y轴位置嵌入以下饼图:

pies <- d %>%
  rowwise() %>%
  group_map(~ plot_ly(.x) %>% 
              add_pie(values = ~ c(val, total - val),
                      marker = list(colors = c("#440154FF", "#FDE725FF"))))

需求:

  1. 理想状态下x轴仅延伸至40
  2. 饼图下方无可见坐标轴
  3. 修正饼图与条形图的颜色不匹配问题
解决方案

核心调整点

  • 把主图x轴范围设为0-40,不占用额外刻度空间
  • 将饼图转为无元素的图片嵌入主图,避免自带坐标轴干扰
  • 统一饼图和条形图的颜色顺序,确保匹配
  • 精准定位饼图到对应y轴分类位置

完整代码

library(dplyr)
library(plotly)
library(tidyr)

# 构建数据,添加y轴分类对应的数值坐标
d <- tibble(cat = LETTERS[1:3],
            val = c(25, 10, 30),
            total = 40) %>%
  mutate(remaining = total - val,
         y_pos = as.numeric(factor(cat)))

# 生成堆叠条形图,x轴范围设为0-40
bars <- d %>%
  pivot_longer(cols = c(val, remaining)) %>% 
  plot_ly(x = ~value, y = ~cat, 
          type = "bar", 
          orientation = 'h', color = ~name, 
          colors = c("#440154FF", "#FDE725FF")) %>%
  layout(xaxis = list(title = NA, range = c(0, 40)),
         yaxis = list(title = NA),
         showlegend = FALSE,
         barmode = "stack")

# 生成无冗余元素的饼图,转为base64图片
pie_images <- d %>%
  rowwise() %>%
  group_map(function(.x, .y) {
    pie <- plot_ly(.x) %>%
      add_pie(values = ~c(val, remaining),
              marker = list(colors = c("#440154FF", "#FDE725FF")),  # 和条形图颜色顺序一致
              showlegend = FALSE) %>%
      layout(xaxis = list(visible = FALSE),
             yaxis = list(visible = FALSE),
             annotations = list(),
             margin = list(l = 0, r = 0, t = 0, b = 0))
    
    plotly::plotly_image(pie, width = 60, height = 60)
  }) %>%
  unlist()

# 将饼图图片嵌入主图指定位置
for (i in seq_along(pie_images)) {
  bars <- bars %>%
    add_layout_images(
      list(
        source = pie_images[i],
        x = 50,
        y = d$y_pos[i],
        xref = "x",
        yref = "y",
        sizex = 8,
        sizey = 0.8,
        xanchor = "center",
        yanchor = "middle"
      )
    )
}

# 显示最终图表
bars

关键说明

  1. x轴范围控制:直接设置主图x轴range = c(0,40),饼图通过图片嵌入叠加在图表上层,不影响x轴刻度
  2. 颜色匹配:饼图values顺序和条形图的val、remaining顺序一致,对应颜色数组也完全相同,解决颜色错位问题
  3. 无坐标轴饼图:生成饼图时隐藏所有坐标轴、标题、边距,只保留饼图图形,转为图片后嵌入就不会出现多余坐标轴
  4. 位置精准度:把分类变量cat转为数值型y_pos,确保每个饼图精准对应到对应的y轴分类位置

内容的提问来源于stack exchange,提问作者thothal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 19:52:43