大数跨境

富集分析出图不好看?试试棒棒糖图

富集分析出图不好看?试试棒棒糖图 SCIPainter
2026-10-28
3
导读:WorkBuddy轻松搞定!
推荐公众号奥智生物,分享前沿组学技术、实用生信技能、数据挖掘思路


基因功能富集分析是转录组、蛋白组等组学数据分析中最常见的流程,而棒棒糖图(Lollipop Plot)因其简洁直观,常用于展示 GO、KEGG 各分类条目富集到的目的基因数量,如下图。


下面就以上图为例,看下如何用 WorkBuddy 绘制这样的棒棒糖图吧!

01

提交绘图需求


先准备绘图数据,这里的绘图数据结构如下,包含 GO 三大类、GO ID、GO 条目名称和富集基因数 4 列,如下图。

在 WorkBuddy 中新建任务,把参考图和绘图数据放入工作文件夹中,然后提交绘图需求指令即可。


参考指令:
以当前工作空间中的 “0.1.png” 为参考图,以 “GOleve2.csv” 文件作为绘图数据,使用 R 语言复现出这样的棒棒糖图(Lollipop plot),给出绘图代码,要求绘图步骤详细,避免函数嵌套,配色方案与参考图一致

提交需求之后,大约十几分钟左右,绘图任务完成!WorkBuddy 按照我们的需求生成了作图所用的 R 代码和示例图。初始的绘图效果已经相当接近原图,不过图例在右侧占了不少横向空间,可做继续调整。


02

图形样式调整


我这里直接用 RStudio 打开 WorkBuddy 给出的 R 脚本进行样式调整。注意,在读入绘图数据前确定工作目录,如下图。


然后逐段运行脚本,初始绘图效果如下,已经非常接近参考图了。


不过图例在右侧,占据了不少横向空间,这里把图例位置从右侧改为顶部,同时用让图例里的圆点小一点,调整效果如下图。


当然,如果对原图的配色不满意,也可以改为自己喜欢的配色,只需替换掉步骤 6 中的三个色号即可,横轴标签颜色会自动同步,如下图。


最终得到的棒棒糖图如下:


参考绘图代码:
## 步骤 1:加载需要的包library(ggplot2)   # 绘图核心library(ragg)      # 高质量 PNG 设备:字体渲染与抗锯齿更接近参考图## 步骤 2:读取数据# 把工作目录切到脚本所在目录(RStudio 中也可手动 Session -> Set Working Directory)dat <- read.csv("GOleve2.csv",                header           = TRUE,                stringsAsFactors = FALSE,                fileEncoding     = "UTF-8")head(dat)## 步骤 3:整理列名与类型(原列名较长,改成短名,后面写代码更清爽)names(dat) <- c("go_class", "go_id", "term", "count")dat$go_class <- trimws(dat$go_class)     # 去掉首尾空格,避免分组识别失败dat$term     <- trimws(dat$term)dat$count    <- as.numeric(dat$count)    # 确保是数值型## 步骤 4:固定 GO 三大类的顺序(决定图例顺序与横轴分组顺序)class_levels <- c("Biological Process",                  "Cellular Component",                  "Molecular Function")dat$go_class <- factor(dat$go_class, levels = class_levels)## 步骤 5:排序 —— 先按大类,再按 count 从大到小## order() 是稳定排序,并列值(如两个 43、两个 8)会保持 CSV 里的原始先后class_code <- as.integer(dat$go_class)   # BP=1, CC=2, MF=3row_order  <- order(class_code, -dat$count)dat <- dat[row_order, ]rownames(dat) <- NULL                    # 重排行号## 步骤 6:配色方案(三个色值直接取自参考图 0.1.png 的像素颜色)pal <- c("Biological Process" = "#0077C1",   # 蓝         "Cellular Component" = "#00A99E",   # 青绿         "Molecular Function" = "#6BC72B")   # 黄绿pal <- c("Biological Process" = "#9ccc82",            "Cellular Component" = "#88c4e8",            "Molecular Function" = "#b67eb7") ## 步骤 7:构造横轴 —— 用「连续数值坐标」代替「离散因子坐标」## 好处:刻度位置、标签文字、标签颜色三者可以一一对应、精确控制dat$id    <- seq_len(nrow(dat))              # 1, 2, 3, ..., 48http://127.0.0.1:26531/graphics/ff25104f-bca5-44dc-8489-36e1e1cfae64.pngx_breaks  <- dat$id                          # 刻度位置x_labels  <- dat$term                        # 刻度文字x_colours <- pal[as.character(dat$go_class)] # 每个标签对应的颜色,与 x_breaks 同序names(x_colours) <- NULL                     # 去掉 names,否则主题参数会报错## 步骤 8:纵轴刻度(参考图只标 0 / 20 / 40 / 60 四档)y_breaks <- c(0, 20, 40, 60)y_max    <- max(dat$count)                   # 72## 步骤 9:逐层叠加图形(核心三步:棒 -> 点 -> 字)# 9.1 建立画布:只声明数据,不写全局 aes,避免图层之间映射互相干扰p <- ggplot(data = dat)# 9.2 棒:从 y = 0 画到数值处;lineend = "butt" 让线端是平口,与圆点衔接更干净#     棒本身不单独进图例(show.legend = FALSE),图例里只保留圆点p <- p + geom_segment(mapping = aes(x = id, xend = id, y = 0, yend = count,                                    colour = go_class),                      linewidth   = 1,                      lineend     = "butt",                      show.legend = FALSE)# 9.3 糖:圆点压在棒的顶端;stroke = 0 去掉描边,实心圆更饱满p <- p + geom_point(mapping = aes(x = id, y = count, colour = go_class),                    size   = 6.6,                    stroke = 0)# 9.4 数值:白色粗体写在圆点正中间(圆点与数字同坐标,所以天然居中)p <- p + geom_text(mapping = aes(x = id, y = count, label = count),                   colour      = "white",                   size        = 2.9,                   fontface    = "bold",                   family      = "Arial",                   show.legend = FALSE)## 步骤 10:标度(scales)# 10.1 颜色:手动指定三组配色;name = NULL 让图例没有标题p <- p + scale_colour_manual(values = pal, name = NULL)# 10.2 横轴:连续坐标 + 自定义刻度位置与文字#      add = 0.7 让左右两端各留不到一个刻度的空隙,边缘圆点不会被裁掉p <- p + scale_x_continuous(breaks = x_breaks,                            labels = x_labels,                            expand = expansion(add = 0.7))# 10.3 纵轴:范围 0-72,只显示 4 个刻度#      mult = 0.05 上下各留 5% 空白,与参考图的留白比例一致(0 刻度线下方留白更明显)p <- p + scale_y_continuous(limits = c(0, y_max),                            breaks = y_breaks,                            expand = expansion(mult = c(0.05, 0.05)))## 步骤 11:主题细节(无边框、无网格、无坐标轴线,只保留刻度线)# 11.1 以 theme_classic 为底(自带白底、无网格),指定基础字号与字体t <- theme_classic(base_size   = 12,                   base_family = "Arial")# 11.2 去掉坐标轴线(参考图没有 y 轴线,也没有 x 轴线)t <- t + theme(axis.line  = element_blank(),               panel.grid = element_blank())# 11.3 刻度线:黑色小竖杠t <- t + theme(axis.ticks        = element_line(colour = "black", linewidth = 0.55),               axis.ticks.length = unit(3.2, "pt"))# 11.4 横轴标签:旋转 90 度、右对齐到刻度、按所属大类上色#      (ggplot2 允许 colour 传入与标签等长的颜色向量,会逐条对应;#        运行时提示 "Vectorized input to element_text() is not officially supported",#        属于「未正式支持但可正常工作」的提示,可忽略)t <- t + theme(axis.text.x = element_text(angle  = 90,                                          hjust  = 1,                                          vjust  = 0.5,                                          size   = 11,                                          colour = x_colours,                                          margin = margin(t = 4)))# 11.5 纵轴刻度文字与轴标题:深灰色 (#4D4D4D),标题字号略大t <- t + theme(axis.text.y  = element_text(colour = "#4D4D4D", size = 10),               axis.title.y = element_text(colour = "#4D4D4D",                                           size   = 12,                                           margin = margin(r = 8)))# 11.6 去掉横轴标题t <- t + theme(axis.title.x = element_blank())# 11.7 图例:右侧、无标题、无底色、无边框t <- t + theme(legend.position   = "top",               legend.title      = element_blank(),               legend.text       = element_text(size = 9.5, colour = "#4D4D4D"),               legend.key        = element_blank(),               legend.background = element_blank(),               legend.margin     = margin(l = 3, r = 0))# 11.8 画布留白t <- t + theme(plot.margin = margin(t = 20, r = 20, b = 20, l = 20, unit = "pt"))# 11.9 把主题套到图上p <- p + t# 11.10 纵轴标题p <- p + labs(y = "Number", x = NULL)+  guides(color = guide_legend(override.aes = list(size = 4)))## 步骤 12:预览与导出# 12.1 在 RStudio 里会直接在 Plots 面板预览(命令行 Rscript 运行时跳过,避免 pdf 设备不认 Arial)if (interactive()) print(p)# 12.2 导出 PNG: out_file <- "GO_lollipop.png"ggsave(filename = out_file,       plot     = p,       device   = ragg::agg_png,   # 换成 device = cairo_pdf 可导出矢量 PDF       width    = 11,       height   = 5.85,       units    = "in",       dpi      = 200,       bg       = "white")cat("图片已保存至:", normalizePath(out_file), "\n")

好啦,本次使用 WorkBuddy 绘制富集分析棒棒糖图的教程就分享到这里啦!

*未经许可,不得以任何方式复制或抄袭本篇文章之部分或全部内容。版权所有,侵权必究。


图片
图片
# SCIPainter

基迪奥旗下绘图公众号

分享科研绘图技能与工具

欢迎关注与转发~


图片

你的好友拍了拍你

并请你帮她点一下“分享”~

【声明】内容源于网络
0
0
SCIPainter
“一图胜千言”,好看的图形千篇一律,丑的配图千奇百怪。SCIPainter,旨在分享科研绘图的技能与工具。不保证日更,有时间就做线上培训,不排除录制付费视频的可能。如果你想看我日更,请多把我分享出去,说不定我就文思如尿崩了。
内容 957
粉丝 0
SCIPainter “一图胜千言”,好看的图形千篇一律,丑的配图千奇百怪。SCIPainter,旨在分享科研绘图的技能与工具。不保证日更,有时间就做线上培训,不排除录制付费视频的可能。如果你想看我日更,请多把我分享出去,说不定我就文思如尿崩了。
总阅读12.4k
粉丝0
内容957