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)

但由于數據本身的原因不含異常值,因此顯示不出來,代碼貼出來供學習使用。


文章已發布到微信公眾號:百味科研芝士,歡迎關注。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容