R ggplot分面饼图实现:让所有饼图呈现相对占比而非完整圆形
问题
我需要在R的ggplot中绘制分面饼图,涉及3个维度。目前实现了两种效果:
- 使用
geom_bar(stat="identity",...,position=position_fill())时,3个饼图均为完整圆形; - 使用
position=position_stack()时,仅1个饼图为完整圆形,另外两个为部分圆形。
希望所有饼图都以部分圆形呈现,代表其相对整体的占比(A约70%,B约20%,C约10%),请问如何实现?
可复现代码
df<-structure(list(x = structure(c(11L, 10L, 9L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 17L, 16L, 15L, 14L, 13L, 12L, 20L, 19L, 18L), levels = c("x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20" ), class = "factor"), prop = c(10.4723707664884, 8.33333333333333, 7.79857397504456, 7.70944741532977, 7.62032085561497, 7.39750445632799, 6.95187165775401, 5.88235294117647, 2.94117647058824, 2.76292335115865, 2.18360071301248, 4.23351158645276, 3.83244206773619, 3.6096256684492, 3.29768270944742, 2.89661319073084, 2.22816399286988, 4.76827094474153, 2.67379679144385, 2.40641711229947), dim = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "C", "C", "C")), row.names = c(NA, -20L), class = "data.frame") colorramps<-c(paletteer_c("ggthemes::Green", 11), paletteer_c("ggthemes::Classic Blue", 6), paletteer_c("ggthemes::Purple", 3) )
解决方案
要实现所有饼图以部分圆形呈现,核心是统一所有分面的y轴范围为0到100(对应整体占比的100%),让每个维度的堆叠总和直接对应其在整体中的占比。具体修改如下:
修改后的代码
# 可选:计算每个维度的总占比用于验证 library(dplyr) df_total <- df %>% group_by(dim) %>% summarise(total_prop = sum(prop)) print(df_total) # 绘制部分圆形分面饼图 x11(25,12) ggplot(df,aes(x="", y=prop, fill=x))+ geom_bar(stat="identity", width=1, col="black", position = position_stack())+ facet_grid(~dim)+ coord_polar("y", start=0)+ # 统一y轴范围为0-100,确保所有分面的圆形基准一致 ylim(0, 100)+ scale_fill_manual(values = colorramps) + geom_text(aes(label = round(as.numeric(prop), digits=0)), position = position_stack(vjust=0.5)) + labs(x = NULL, y = NULL, fill = NULL)+ theme_classic()+ theme(axis.line = element_blank(), axis.text = element_blank(), axis.ticks = element_blank())+ labs(title = "Proportion of x by dimension (Partial Circles)")
关键说明
ylim(0, 100):强制所有分面的y轴范围统一为0到100,这样每个维度的堆叠总和(比如A的总和约70)会在这个范围内显示为对应比例的部分圆形;- 保留
position=position_stack():按原始数值堆叠,而非将每个分面的数值归一化到100%; - 文本位置使用
position_stack(vjust=0.5),确保每个分段的标签居中显示。
内容的提问来源于stack exchange,提问作者michel
相关产品推荐
相关产品推荐

