基于R语言ggforce包geom_arc_bar绘制分组学科均值环形图方法咨询
具体实现步骤
步骤1:数据预处理
首先需要先将宽表数据转为长表,再计算每个分组对应四门学科的平均成绩:
# 加载所需包 library(tidyverse) # 示例数据,固定随机种子方便复现结果 set.seed(123) df <- data.frame(English = sample(1:100,10), Math = sample(1:100,10), History = sample(1:100,10), Science = sample(1:100,10), Group = rep(c("A","B","C","D","E"),each=2)) # 宽表转长表+计算分组学科均值 df_mean <- df %>% pivot_longer(cols = -Group, names_to = "Subject", values_to = "Score") %>% group_by(Group, Subject) %>% summarise(mean_score = mean(Score), .groups = "drop")
方案1:使用ggforce包的geom_arc_bar实现
匹配你提到的实现函数,逻辑更直观:
# 提前安装包:install.packages("ggforce") library(ggforce) # 补充绘图所需的角度、半径参数 df_arc <- df_mean %>% mutate( # 四门学科均分2π圆周,每门占π/2弧度,分配起始/结束弧度 start = case_when( Subject == "English" ~ 0, Subject == "Math" ~ pi/2, Subject == "History" ~ pi, Subject == "Science" ~ 3*pi/2 ), end = start + pi/2, # 给分组分配环形内外半径,从内到外依次为A/B/C/D/E组 group_num = as.numeric(factor(Group, levels = c("A","B","C","D","E"))), r0 = group_num * 0.7, # 环形内半径 r = r0 + 0.6 # 环形外半径 ) # 绘图 ggplot() + geom_arc_bar(data = df_arc, aes(x0 = 0, y0 = 0, r0 = r0, r = r, start = start, end = end, fill = Subject, alpha = mean_score)) + coord_fixed() + # 固定坐标轴比例避免环形变形 # 添加分组标签 annotate("text", x = 0, y = c(1,1.7,2.4,3.1,3.8), label = c("A组","B组","C组","D组","E组"), size = 3) + scale_fill_brewer(palette = "Set2") + labs(fill = "学科", alpha = "平均成绩") + theme_void() # 清空多余背景元素
注:如果需要弧长而非透明度对应均值大小,只需把end参数修改为end = start + (mean_score/100)*pi/2即可,此时每个学科的弧长会和成绩成正比。
方案2:ggplot2原生实现(无需安装ggforce)
使用原生geom_rect配合极坐标也可实现同等效果:
# 补充绘图参数 df_polar <- df_mean %>% mutate( # 学科对应x轴区间 subject_num = as.numeric(factor(Subject, levels = c("English","Math","History","Science"))), xmin = subject_num - 1, xmax = subject_num, # 分组对应y轴区间 group_num = as.numeric(factor(Group, levels = c("A","B","C","D","E"))), ymin = group_num * 2 - 1.5, ymax = group_num * 2 - 0.5 ) # 绘图 ggplot(df_polar) + geom_rect(aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = Subject, alpha = mean_score)) + coord_polar(theta = "x") + # 转极坐标,x轴对应圆周方向 # 设置x轴刻度为学科名称 scale_x_continuous(breaks = c(0.5,1.5,2.5,3.5), labels = c("English","Math","History","Science")) + # 设置y轴刻度为分组名称 scale_y_continuous(breaks = c(1,3,5,7,9), labels = c("A组","B组","C组","D组","E组")) + scale_fill_brewer(palette = "Set2") + labs(fill = "学科", alpha = "平均成绩", x = "", y = "") + theme_bw() + theme(panel.grid = element_blank())
如果需要弧长对应成绩,把xmax参数修改为xmax = xmin + (mean_score/100)即可。
内容的提问来源于stack exchange,提问作者Jeff238
相关产品推荐
相关产品推荐

