如何用ggplot2制作双层饼环图?适配自定义数据结构
用ggplot2实现双层饼环图(内圈Expression,外圈Substrate)
完全可以用ggplot2实现你的需求,下面是适配你数据结构的完整方案:
步骤1:准备数据与预处理
先构造一份和你结构一致的示例数据,你可以直接替换成自己的数据集:
library(tidyverse) library(geomtextpath) # 构造示例数据 df <- tibble( Expression = c("Up-reg", "Down-reg", "Down-reg", "Up-reg", "Up-reg", "Down-reg", "Up-reg", "Down-reg"), Substrate = c("Glucose", "Fructan", "Acetate", "Benzoate", "Glucose", "Acetate", "Benzoate", "Fructan") ) # 数据预处理:统计各分组数量,计算饼图角度范围 df_processed <- df %>% # 统计每个Expression-Substrate组合的数量 count(Expression, Substrate, name = "count") %>% # 统计每个Expression的总数量(用于内圈计算) group_by(Expression) %>% mutate(total_expr = sum(count)) %>% ungroup() %>% # 按Expression分组,计算每个Substrate对应的x轴角度范围 group_by(Expression) %>% mutate( xmin = c(0, head(cumsum(count), -1)), xmax = cumsum(count), xmid = (xmin + xmax)/2 ) %>% ungroup() %>% # 计算内圈Expression的x轴角度范围 group_by(Expression) %>% mutate( expr_xmin = first(xmin), expr_xmax = last(xmax), expr_xmid = (expr_xmin + expr_xmax)/2 ) %>% ungroup()
步骤2:绘制双层饼环图
ggplot() + # 绘制外圈:Substrate层,y范围2-3对应外圈半径 geom_rect( data = df_processed, aes( xmin = xmin, xmax = xmax, ymin = 2, ymax = 3, fill = Expression, color = Expression ), alpha = 0.8 ) + # 绘制外圈标签 geom_textpath( data = df_processed, aes(x = xmid, y = 2.8, label = Substrate, group = Substrate), size = 4 ) + # 绘制内圈:Expression层,y范围1-2对应内圈半径 geom_rect( data = distinct(df_processed, Expression, expr_xmin, expr_xmax, total_expr), aes( xmin = expr_xmin, xmax = expr_xmax, ymin = 1, ymax = 2, fill = Expression, color = Expression ), alpha = 1 ) + # 绘制内圈标签(包含分组数量) geom_textpath( data = distinct(df_processed, Expression, expr_xmid, total_expr), aes(x = expr_xmid, y = 1.5, label = paste(Expression, total_expr), group = Expression), size = 4.5, fontface = "bold" ) + # 自定义颜色 scale_fill_manual(values = c("Up-reg" = "#2ecc71", "Down-reg" = "#e74c3c")) + scale_color_manual(values = c("Up-reg" = "#27ae60", "Down-reg" = "#c0392b")) + # 转换为极坐标,x轴对应角度,y轴对应半径 coord_polar(theta = "x") + # 设置y轴范围,隐藏刻度 scale_y_continuous(limits = c(0, 3.2)) + # 清除默认主题元素 theme_void() + # 调整图例位置(不需要可设为"none") theme(legend.position = "bottom")
关键说明
- 饼环图本质是极坐标下的矩形图:通过设置不同的
ymin/ymax区分内圈和外圈的半径范围 - 预处理时分别计算内圈、外圈的角度范围,确保外圈分段完全对应内圈的分组归属
- 所有颜色、标签位置、字体样式等元素都可自由调整,完全兼容ggplot2的自定义逻辑
内容的提问来源于stack exchange,提问作者nomad
相关产品推荐
相关产品推荐

