你是不是也觉得——
GraphPad很好用,但一到组图排版、配色微调、个性化注释,就开始头疼。
更别提正版软件的付费提醒时不时弹出来,实验室还只有一台电脑有装。
其实,在R语言里,散点图、箱线图、柱状图这三张基础图,只需要几行代码就能轻松搞定,而且配色、字体、分辨率完全可控,审稿人再挑剔也能应对。
今天师姐就用你RNA-seq分析里一定会用到的场景,带你画出你的第一张SCI级别基础图形。
读完这篇,你将学会:
用 plot 画散点图,并给它换颜色、加标题;
用 boxplot 画分组箱线图,一眼看清差异;
用 barplot 画柱状图,给柱子加上误差棒。
01 画图前的数据准备
我们先造一套很常见的表达量数据,模拟两个基因(TP53和BRCA1)在两组样本(Control和Treatment)里的表达值。
gene <- rep(c("TP53", "BRCA1"), each = 6)
group <- rep(c("Control", "Treatment"), times = 6)
expression <- c(120, 135, 118, 145, 122, 130, # TP53 Control
150, 158, 148, 162, 155, 160, # TP53 Treatment
85, 88, 82, 90, 86, 84, # BRCA1 Control
95, 98, 92, 102, 99, 101) # BRCA1 Treatment
df <- data.frame(gene, group, expression)
head(df)

后面我们会按需要取子集画图。
02 散点图 plot():看清每个点的分布
场景: 我想单独看一下TP53基因所有12个测量值的分布。
先把TP53的数据提出来:
tp53 <- df[df$gene == "TP53", "expression"]
tp53 # 12个数字

最简单的散点图:
plot(tp53)

横坐标自动变成1到12的序号,纵坐标是表达值。
加点修饰,让它能直接放进PPT:
plot(tp53,
main = "TP53 Expression Scatter Plot", # 大标题
xlab = "Measurement Index", # X轴说明
ylab = "Expression Level", # Y轴说明
col = "#2C3E50", # 点的颜色
pch = 19, # 点的样式:实心圆
cex = 1.5) # 点的大小
pch 取值0-25,做生信最常用的就是 19(实心圆)和 1(空心圆)。

如果想看两组对比的散点图, 那就更推荐箱线图来呈现,因为散点密集的时候不容易看出差异。
03 箱线图 boxplot():组间差异一眼看清
公式格式:数值列 ~ 分组列
画TP53在Control和Treatment两组的表达量箱线图:
# 取TP53的全部行
tp53_data <- df[df$gene == "TP53", ]
boxplot(expression ~ group,
data = tp53_data,
main = "TP53 Expression by Group",
xlab = "Group",
ylab = "Expression",
col = c("#3498DB", "#E74C3C")) # Control蓝色,Treatment红色

箱线图怎么读?中间那条粗线是中位数,盒子上下边分别是第一和第三四分位数,上下须触到大部分正常值的范围,须外的圈圈就是离群值。
SCI实用技巧——把两组所有点都叠加在箱线图上:
用 boxplot 画好箱子,再用 stripchart 把原始点加进去。
boxplot(expression ~ group, data = tp53_data,
main = "TP53 Expression with Data Points",
col = c("#3498DB50", "#E74C3C50"), # 最后两位是透明度
ylim = c(100, 170))
stripchart(expression ~ group, data = tp53_data,
vertical = TRUE, add = TRUE,
pch = 19, cex = 1.2,
col = c("#3498DB", "#E74C3C"))
add = TRUE 是叠加上去的关键参数。两张图一重合,数据分布和个体波动全都展示清楚,这是很多CNS子刊里常见的小图样式。

04 柱状图 barplot():展示均值和误差棒
做柱状图一般是先算好均值和标准差,再画柱子。
第一步,算出各组均值:
means <- tapply(df$expression, list(df$gene, df$group), mean)
means
tapply 会根据基因和分组求平均值,得到一个矩阵。

第二步,画并列柱状图:
barplot(means,
beside = TRUE, # 并排而不是堆叠
legend.text = rownames(means), # 自动添加图例
main = "Gene Expression Comparison",
xlab = "Group",
ylab = "Mean Expression",
col = c("#F39C12", "#8E44AD")) # BRCA1橙色,TP53紫色
beside = TRUE 一定要加,否则柱子会摞起来。

第三步,如果想自己加误差棒(需要先算标准差):
sds <- tapply(df$expression, list(df$gene, df$group), sd)
bp <- barplot(means, beside = TRUE,
main = "Gene Expression with Error Bars",
ylim = c(0, 180),
col = c("#F39C12", "#8E44AD"))
# 加误差棒
arrows(bp, means - sds, bp, means + sds,
angle = 90, code = 3, length = 0.1)
arrows 这个函数这里用来画误差线,angle=90 让末端变成横杠,code=3 表示两头都画,length 控制横杠宽度。

05 R原生绘图 vs ggplot2,我该先学哪个?
这是每个生信新手都会问的问题。
我的建议:先吃透今天讲的这些基础函数,理解透绘图逻辑,再去用ggplot2。
因为:
基础绘图不需要装任何包,打开R就能用;
参数名通用,后面过渡到ggplot2更容易理解;
快速出图验证数据,不用折腾语法。
下期师姐就会带你进入 ggplot2图层语法的世界,你会发现你本周学的一切,都会被一条更优雅的逻辑重新编排,出图质量直接拉升到顶刊水平。
今日总结:师姐送你三张图的代码模板
散点图:
plot(x, main="标题", xlab="X轴", ylab="Y轴", col="颜色", pch=19)
箱线图(带点):
boxplot(y ~ group, data=df, col="颜色")
stripchart(y ~ group, data=df, vertical=TRUE, add=TRUE, pch=19)
柱状图(带误差棒):
bp <- barplot(means, beside=TRUE, legend=TRUE, col=颜色向量)
arrows(bp, means-sds, bp, means+sds, angle=90, code=3, length=0.1)
把这三个模板存好,绝大多数基础图形场景你都覆盖了。
下期预告:
基础图够用了,但还不够美。下期切换到ggplot2模式,师姐教你用图层语法一键给图“穿衣服”,让你的RNA-seq图审稿人看了只说一个词——“Professional”。
这里是两栖生物手册,中科院生物医学在读博士,记录生物医学实验和生物信息学笔记,全平台同名,正在努力成为贴心负责的RNA-seq数据分析者和实验技术分享者~