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

绘制比例化双层圆环图:订单与客户数可视化问题

比例化双圆环图实现方案

需要绘制双比例圆环图:外层圆环对应订单总数(16836),内层圆环对应唯一客户数(9017)。当前使用ggforce::geom_circle的代码未实现比例显示(圆环位置和半径设置错误),尝试geom_point仅得到极小的点,现提供修正方案及替代实现方法。

当前问题代码:

library(ggforce) 

X <- structure(list(n = c(16836L, 9017L), Type = c("Total n order", "Unique customers")), 
               row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame"))

ggplot(X) + 
  geom_circle(
    aes(x0 = 0, y0 = n, r = n),
    linewidth =4,
    colour="black"
  ) + 
  geom_circle(
    aes(x0 = 0, y0 = n, r = n),
    linewidth =1,
    colour = "white"
  ) + 
  coord_flip() + 
  theme(aspect.ratio = 1)

方案一:修正ggforce实现比例圆环

原代码问题在于将y0和r绑定到原始大数值,导致圆环中心错位、半径超出画布。需将两个圆环置于同一中心,对半径做缩放处理,通过线宽或半径差实现圆环效果。

代码示例:

library(ggforce)
library(dplyr)

# 缩放数值至合理范围,避免半径过大
X_scaled <- X %>% mutate(scaled_n = n / max(n) * 5)

ggplot() +
  # 外层圆环:对应订单总数
  geom_circle(aes(x0 = 0, y0 = 0, r = X_scaled$scaled_n[1]), 
              linewidth = 2.5, colour = "#2c3e50") +
  # 内层圆环:对应唯一客户数
  geom_circle(aes(x0 = 0, y0 = 0, r = X_scaled$scaled_n[2]), 
              linewidth = 2.5, colour = "#3498db") +
  # 中心空白填充(可选)
  geom_circle(aes(x0 = 0, y0 = 0, r = 1), fill = "white", colour = NA) +
  # 强制圆形比例,隐藏冗余元素
  coord_fixed() +
  theme_void() +
  # 添加比例标注
  annotate("text", x = 0, y = 0, 
           label = paste0("客户数/订单数\n", round(9017/16836*100, 1), "%"), 
           size = 4, colour = "#2c3e50")

方案二:用geom_point实现比例圆环

利用shape = 21(空心圆)结合size映射缩放后的数值,通过stroke控制边框厚度,快速实现圆环效果:

library(ggplot2)

# 缩放数值至适配size参数的范围
X_scaled <- X %>% mutate(scaled_n = n / max(n) * 100)

ggplot(X_scaled, aes(x = 0, y = 0, size = scaled_n, colour = Type)) +
  geom_point(shape = 21, fill = "white", stroke = 3) +
  # 自定义size范围,确保比例正确
  scale_size_continuous(range = c(20, 40)) +
  # 自定义颜色
  scale_colour_manual(values = c("#2c3e50", "#3498db")) +
  coord_fixed() +
  theme_void() +
  guides(size = "none") # 隐藏size图例

方案三:用circlize包实现环形图

circlize专为环形可视化设计,代码简洁直观:

library(circlize)

# 设置画布参数
circos.par(start.degree = 90, track.height = 0.15, 
           canvas.xlim = c(-1, 1), canvas.ylim = c(-1, 1))
circos.initialize(factors = "a", xlim = c(0, 1))

# 绘制外层圆环(订单总数)
circos.trackPlotRegion(ylim = c(0.8, 1), bg.border = "#2c3e50", bg.lwd = 3)
# 绘制内层圆环(按客户数与订单数的比例缩小半径)
inner_radius <- 9017 / 16836
circos.trackPlotRegion(ylim = c(inner_radius - 0.15, inner_radius), 
                       bg.border = "#3498db", bg.lwd = 3)

# 关闭circlize绘图设备
circos.clear()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:38:38