R繪圖(7): 把散點圖的點換成扇形

TOP生物資訊發表於2021-07-22

前幾天分析了一批單細胞TCR的資料,需要畫這樣一個圖:

行是不同的樣本,列是不同的T細胞型別,每一個位置點的大小表示T細胞的數目多少,並且還需要根據T細胞所屬的克隆型型別塗色。這個圖用來描述TCR是我自己構思的,之前沒有在文章中見過。好在畫圖工具是現成的,用的是餘老師的scatterpie包。後臺回覆20210722即可獲取本文的測試資料。

1. 匯入測試資料

library(tidyverse)
library(scatterpie)
library(reshape2)

df1=read.table("test.txt",header = T,row.names = 1,sep = "\t",stringsAsFactors = F)

看一下資料格式

> head(df1)
sample celltype clonal_expansion
TTAGTTCGTTCGGCAC tumor5        E                1
ATAACGCGTGAGGCTA tumor5        A        morethan3
CTCTAATCAACACCTA tumor1        B                1
AGACGTTAGTGTGGCA tumor5        A                1
AGATCTGTCACGGTTA tumor5        C                1
TCAGCTCTCGGCGCAT tumor3        A                1

> table(df1$sample,df1$celltype)
A   B   C   D   E   F   G
tumor0  12  60   2   0  21  13   5
tumor1  42 225  65   6  75  59  19
tumor3  44  79  20   4  26  51   6
tumor5 283 134 209  97  23 334  86

> table(df1$clonal_expansion,df1$celltype)

A   B   C   D   E   F   G
1         230 485 212  92 128 364 107
2          68   8  28  12   9  54   6
morethan3  83   5  56   3   8  39   3

原始資料框有4個腫瘤樣本,7個T細胞型別。
clonal_expansion表示這個T細胞所屬的TCR克隆型總共有幾個細胞(這幾個細胞的TCR克隆型是一樣的)

2. 資料轉換

長資料轉寬資料

df3=df1 %>% dcast(sample+celltype~clonal_expansion)

reshape2包的dcast函式可以將長資料轉化為寬資料,
這一步之後,每一行表示在一定的sample、一定的celltype之下,不同的clonal_expansion分組各有多少個值
(預設的整合函式為求和計算)

> head(df3)
sample celltype  1 2 morethan3
1 tumor0        A 12 0         0
2 tumor0        B 60 0         0
3 tumor0        C  2 0         0
4 tumor0        E 19 2         0
5 tumor0        F 13 0         0
6 tumor0        G  5 0         0

除了已知的4個樣本,7種型別,我還希望增加一個虛擬樣本allsample,一個虛擬型別alltype,1乘4+1乘7+1乘1=12,即還需要人為新增12行

df4a=data.frame()
for (samplei in unique(df3$sample)) {
  tmp1=df3 %>% filter(sample == samplei)
  df4a=rbind(df4a,c(sample=samplei,celltype="alltype",colSums(tmp1[,3:5])))
}

df4b=data.frame()
for (typei in unique(df3$celltype)) {
  tmp2=df3 %>% filter(celltype == typei)
  df4b=rbind(df4b,c(sample="allsample",celltype=typei,colSums(tmp2[,3:5])))
}

df4c=data.frame()
df4c=c(sample="allsample",celltype="alltype",colSums(df3[,3:5]))

colnames(df4a)=colnames(df3)
colnames(df4b)=colnames(df3)
df4=rbind(df4a,df4b) %>% rbind(df4c)
df4$`1`=as.numeric(df4$`1`)
df4$`2`=as.numeric(df4$`2`)
df4$morethan3=as.numeric(df4$morethan3)
df5=df3 %>% rbind(df4)

3. 畫圖

貌似這個R包不支援字元,所以這裡我將字元人為轉換為數字

df5$sample=ifelse(df5$sample=="tumor0",-1,
                    ifelse(df5$sample=="tumor1",-2,
                           ifelse(df5$sample=="tumor3",-3,
                                  ifelse(df5$sample=="tumor5",-4,-5))))

df5$celltype=ifelse(df5$celltype=="A",1,
                      ifelse(df5$celltype=="B",2,
                             ifelse(df5$celltype=="C",3,
                                    ifelse(df5$celltype=="D",4,
                                           ifelse(df5$celltype=="E",5,
                                                  ifelse(df5$celltype=="F",6,
                                                         ifelse(df5$celltype=="G",7,8)))))))

設定配色

library(RColorBrewer)
library(scales)
color_ce=brewer.pal(9, "YlGnBu")[c(3,5,8)]
names(color_ce)=c("1","2","morethan3")

新增一列半徑,用每一行細胞數的和對映

df5$radius=log2(rowSums(df5[,3:5])) / 25 #這個公式不唯一,保證細胞多的時候圖形大就可以了

以下是畫圖主要程式碼:

ggplot() + geom_scatterpie(aes(x=celltype, y=sample, r=radius), data=df5,cols=colnames(df5)[3:5],color=NA) + #cols參數列示用那幾列來畫扇形
  geom_hline(yintercept = -4.5,linetype=5)+
  geom_vline(xintercept = 7.5,linetype=5)+
  geom_scatterpie_legend(df5$radius, x=3.5, y=-1.3,n=4,labeller = function(x) round(2^(x*25)))+ #n參數列示圖例顯示幾個圓;labeller是一個函式,通過這個函式可以反推出真實數值
  coord_equal()+
  scale_fill_manual(values = color_ce)+
  scale_x_continuous("",expand = c(0,0),breaks = 1:8,labels = c("A","B","C","D","E","F","G","alltype"))+
  scale_y_continuous("",expand = c(0,0),breaks = -5:-1,labels = c("allsample","tumor5","tumor3","tumor1","tumor0"))+
  theme_bw()+
  theme(
    panel.grid = element_blank(),
    legend.title = element_blank()
  )
ggsave("clonal_expansion_pie.pdf",width = 20,height = 15,units = "cm")

之後就能得到封面那張圖了。

因水平有限,有錯誤的地方,歡迎批評指正!

相關文章