ggplot2:如何优雅地绘制箱线图

数据可视化是将数据直观展示出来的一个必不可少的步骤。ggplot2是一个非常常见的绘图R包,在文献中,我们常常会看见用漂亮箱线图来展示原始数据的分布。这里我们就用一个基因表达水平的例子来展示用R包绘图神器ggplot2绘制的过程吧!

Step1:数据的预处理

这里我们利用GEO中单细胞RNA测序数据来练练手。
数据来源:
https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE128147

在R中读取这个数据:

counts = read.table("~/Downloads/GSE128147_raw_counts_w_ercc.txt", header = TRUE)

我们可以得到行是基因名,列是细胞名,中间的数值为表达量。也就是每个基因在每个细胞中的表达量,这种数据称为raw counts。如图所示:
数据展示
dim(counts)
[1] 23512   193

这里数据一共有193个细胞,通常我们有某种研究目的时,需要看某几类细胞的表达情况,那么根据细胞名或其他指标将它们区分开。

由于这里仅为了学习如何作图,那么为了方便,只取几种基因,并将这些细胞按照顺序粗暴地分为3组,每组64个,每组分别命名为CellType1, CellType2, CellType3,计算每个基因在各类细胞中的表达水平(求和),并整理成一个数据框,变量名为expres。整理代码如下:

## 将原始数据截取出左、中、右三段
type1 = counts[,1:65]
type2 = counts[,c(1,66:129)]
type3 = counts[,c(1,130:193)]

## 将每个基因在每种细胞内的表达量求和,并将结果添加到数据框中
type1 = within(type1,{sum.of.expression = rowSums(type1[-1])})
type2 = within(type2,{sum.of.expression = rowSums(type2[-1])})
type3 = within(type3,{sum.of.expression = rowSums(type3[-1])})

## 只取出第1列基因名与最后一列表达水平之和
type1 = type1[,c(1,66)]
type2 = type2[,c(1,66)]
type3 = type3[,c(1,66)]

## 将三个向量合并为一个数据框
expres = data.frame(Gene = type1[,1], 
                    CellType1 = type1[,2], 
                    CellType2 = type2[,2], 
                    CellType3 = type3[,2])

这么一来得到的数据就是这样:
数据展示2
> head(expres)
    Gene CellType1 CellType2 CellType3
1   Xkr4         0         0         0
2    Rp1         0      1249         4
3  Sox17         0         0         0
4 Mrpl15        12      2172      1483
5 Lypla1       268      1956      2235
6  Tcea1       206       508      1443

将数据变形,利于后续作图。

library(reshape2)
expres.melt = melt(expres, value.name = "Counts")
# Using Gene as id variables
# ggplot2常用melt型数据
expres.melt = subset(expres.melt, Counts > 300 & Counts < 10000) 
# 筛选掉一些表达量过少和过多的基因

expres.melt$Counts = log(expres.melt$Counts) 
#由于表达量绝对值差距太大,因此用对数将数据标准化

head(expres.melt)
      Gene  variable   Counts
8  Atp6v1h CellType1 6.967909
11  Rb1cc1 CellType1 7.502186
14  Pcmtd1 CellType1 5.910797
16    Rrs1 CellType1 7.092574
21  Vcpip1 CellType1 8.051978
30 Arfgef1 CellType1 7.686621

Step2:绘制箱线图

1. 画一个基础的箱线图:geom_boxplot()

library(ggplot2)
ggplot(expres.melt, aes(x=variable,y=Counts)) +     
  geom_boxplot(aes(fill=variable))
  • expres.melt即我们的数据;
  • aes(x = 横坐标向量, y = 纵坐标向量);
  • geom_boxplot 箱线图;
  • fill=variable 按照variable类型来填充颜色。

这么一来就得到一个还不错的箱线图:
箱线图1

2. 更改坐标轴标题、图片标题与图例标题:labs()

在刚才的基础上我们想要将图的横坐标、纵坐标以及图的标题进行修改,那么可以使用labs()函数在之前的代码后面进行添加。

ggplot(expres.melt, aes(x=variable,y=Counts)) +     
  geom_boxplot(aes(fill=variable)) +
  labs(title="Expression Level of 3 Types of Cells",
       x="Cell Type", y = "Counts/(log)", fill = "Cell Type")  # fill为修改图例标题
箱线图2

3. 图例的设置:theme()

图例标题的修改比较特殊,不能再用labs了,而是用theme(),同时theme()这个函数还能设置图例的标题的字体、颜色、大小。也能修改总标题的位置。

ggplot(expres.melt, aes(x=variable,y=Counts)) +     
  geom_boxplot(aes(fill=variable)) +
  labs(title="Expression Level of 3 Types of Cells",
       x="Cell Type", y = "Counts/(log)", fill = "Cell Type") +
  theme(plot.title = element_text(hjust = 0.5), # 将图表标题居中
        legend.title=element_text(face="italic",  # 图例标题改为斜体
                                  family="Times",  # 图例标题字体调为Times
                                  colour="red"))  # 图例标题颜色改为红色
箱线图3.jpeg

4.将箱线图转置:coord_flip()

有时候如果数据类型比较多,为了排版方便,可能需要将箱线图转置,这种情况下怎么处理呢?

ggplot(expres.melt, aes(x=variable,y=Counts)) +     
  geom_boxplot(aes(fill=variable)) +
  labs(title="Expression Level of 3 Types of Cells",
       x="Cell Type", y = "Counts/(log)",
       fill = "Cell Type") +
  theme(plot.title = element_text(hjust = 0.5) +
  coord_flip()
箱线图4.jpeg

图形就横过来了。

5.将背景变为白色:theme_bw()

背景的颜色也可以进行修改,这样一来做PPT上组会汇报时白色背景显得更为学术和美观。

ggplot(expres.melt, aes(x=variable,y=Counts)) +     
  geom_boxplot(aes(fill=variable)) +
  labs(title="Expression Level of 3 Types of Cells",
       x="Cell Type", y = "Counts/(log)",
       fill = "Cell Type") +
  theme_bw()
箱线图5.jpeg

除了这些,其实还有许多的功能可以叠加,如增加数据点可叠加散点+geom_dotplot,标注异常值可利用outlier,代码示例:

ggplot(expres.melt, aes(x=variable,y=Counts)) +     
  geom_boxplot(aes(fill=variable),
               outlier.colour="red", 
               outlier.shape=8, 
               outlier.size=4)

但由于数据本身的原因不含异常值,因此显示不出来,代码贴出来供学习使用。


文章已发布到微信公众号:百味科研芝士,欢迎关注。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容