如何在ggplot2中按样本量缩放多个饼图的大小?
按学科总人数调整分面饼图尺寸的解决方案
问题说明
现有R代码通过ggplot2绘制了各学科男女占比的分面饼图,需要将饼图按照对应学科的总学生数(数学158人最大,英语31人最小)从大到小调整尺寸,同时保持分面顺序与总人数排序一致。
修正后的完整代码
library(dplyr) library(ggplot2) # 数据处理:计算总人数并排序学科 df <- data.frame(Subjects = c("Literature", "Literature", "Geography", "Geography", "Arts", "Arts", "English", "English", "Math", "Math", "History", "History", "Biology", "Biology", "French", "French"), Sex = rep(c("Girls", "Boys"), 8), # 修正原代码重复次数错误 N = c(15, 20, 30, 22, 77, 40, 14, 17, 80, 78, 52, 65, 32, 56, 89, 41)) %>% group_by(Subjects) %>% mutate(total_N = sum(N), # 计算每个学科总人数 pct = proportions(N) * 100) %>% mutate(pct = round(pct, 1)) %>% ungroup() %>% # 将学科按总人数降序转为有序因子,控制分面顺序 mutate(Subjects = factor(Subjects, levels = arrange(., desc(total_N)) %>% pull(Subjects) %>% unique())) # 绘制带尺寸差异的分面饼图 df %>% ggplot(aes(x = total_N, y = pct, fill = Sex)) + geom_bar(stat = "identity", width = 1, color = "white", na.rm = TRUE) + coord_polar("y", start = 0) + facet_wrap(~ Subjects, ncol = 4, strip.position = "bottom", scales = "free_x") + # 允许x轴自由缩放,实现饼图尺寸差异 geom_text(aes(y = pct, label = paste0(pct, "%")), size = 5, position = position_stack(vjust = 0.5)) + theme_void() + theme(legend.title = element_blank(), strip.text = element_text(size = 12), plot.title = element_text(hjust = 0.0), legend.text = element_text(size = 12), legend.spacing.y = unit(0.0, 'cm'), legend.box.spacing = unit(-2, "pt")) + guides(fill = guide_legend(byrow = TRUE)) + scale_fill_brewer(palette = "Set2") + scale_x_continuous(limits = c(0, NA)) # 确保x轴从0起始,避免饼图偏移
关键修改点
- 修正数据错误:原代码中
rep(c("Girls", "Boys"), 2)无法匹配16行数据,改为rep(c("Girls", "Boys"), 8); - 新增总人数字段:通过
total_N = sum(N)计算每个学科的总学生数; - 控制分面顺序:将
Subjects转为按total_N降序排列的有序因子,让分面从总人数最多的学科开始; - 实现尺寸差异:将x轴映射为
total_N,结合facet_wrap的scales = "free_x"参数,让每个分面的x轴范围独立,极坐标下x轴长度对应饼图半径,从而实现饼图大小与总人数成正比; - 优化饼图位置:添加
scale_x_continuous(limits = c(0, NA))确保x轴从0开始,避免饼图出现偏移。
内容的提问来源于stack exchange,提问作者always.learning
相关产品推荐
相关产品推荐

