绘制比例化双层圆环图:订单与客户数可视化问题
比例化双圆环图实现方案
需要绘制双比例圆环图:外层圆环对应订单总数(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
相关产品推荐
相关产品推荐

