【R畫圖學(xué)習(xí)13.3】散點圖---曼哈頓圖

曼哈頓圖,我自己最常用于的場景就是GWAS分析之后,常使用它展示基因組中與某種表型顯著相關(guān)的SNP位點或基因型信息。一般橫軸是代表染色體,縱軸則表示SNP位點與表型關(guān)聯(lián)的顯著程度,一般-log10(Pvalue),實線一般表示統(tǒng)計學(xué)上的顯著性cutoff。

曼哈頓圖的實現(xiàn)方法,包括現(xiàn)在的形式也是多種多樣,我們先來測試幾個最簡單的。


第一個:qqman包。

library(qqman)

我們測試數(shù)據(jù)用的是這個包自帶的測試數(shù)據(jù)。

data(gwasResults)

head(gwasResults)

manhattan(gwasResults, col = rainbow(22), suggestiveline = -log10(1e-05), genomewideline = -log10(5e-08), annotatePval = 5e-08, annotateTop = FALSE)

suggestiveline:一般是顯著性cutoff

genomewideline:高置信顯著性

annotatePval:If set, SNPs below this p-value will be annotated on the plot。如果設(shè)置,那么高于這個Pvalue的SNP將會被標(biāo)記出來。

annotateTop:If TRUE, only annotates the top hit on each chromosome that is below the annotatePval threshold。如果設(shè)置成TRUE,那么只會標(biāo)記每個染色體上最top的SNP(低于annotatePval)。

第二個:ggplot

library(ggplot2)

library(tidyverse)

因為我們位置是根據(jù)染色體變化的,所以我們需要把位置做個轉(zhuǎn)化,轉(zhuǎn)化成X軸上連續(xù)的坐標(biāo)。但是就會出現(xiàn)一個問題,就是X軸上的刻度和坐標(biāo),我也需要手動設(shè)置,安排好22個染色體的位置。

#計算染色體刻度坐標(biāo)

gwasResults$SNP1 <- seq(1, nrow(gwasResults), 1)

gwasResults$CHR <- factor(gwasResults$CHR, levels = unique(gwasResults$CHR))

chr <- aggregate(gwasResults$SNP1, by = list(gwasResults$CHR), FUN = median)

aggregate函數(shù)是數(shù)據(jù)處理中常用到的函數(shù)??梢园凑找蟀褦?shù)據(jù)打組聚合,然后對聚合以后的數(shù)據(jù)進行加和、求平均等各種操作。

aggregate(x, by, FUN, ..., simplify = TRUE, drop = TRUE)

當(dāng)然也可以用我們前幾期常用的通道操作。

#data_new <- gwasResults %>% group_by(CHR) %>% mutate(mean = mean(SNP1))

#data_new2 <- unique(data_new[,c(2,6)])

colnames(chr) <- c("label","location")

下面我們就可以用ggplot來畫圖了。

ggplot(gwasResults, aes(SNP1, -log10(P)))+

geom_point(aes(color = CHR), show.legend = FALSE) +

scale_color_manual(values = rainbow(22)) +

geom_hline(yintercept = c(-log10(1e-05), -log10(5e-08)), color = c('blue', 'red'), size = 0.35) +

scale_x_continuous(breaks = chr$location, labels = chr$label, expand = c(0, 0)) +

scale_y_continuous(breaks=seq(1,9,2),labels=as.character(seq(1,9,2)),expand = c(0, 0), limits = c(0, 9)) +

theme(panel.grid = element_blank(), axis.line = element_line(colour = 'black'), panel.background = element_rect(fill = 'transparent')) +

labs(x = 'Chromosome', y=expression(-log[10](P)))+

#annotate('rect', xmin = 0, xmax = max(gwasResults$SNP1), ymin = -log10(1e-05), ymax = -log10(5e-08), fill = 'gray98') +? #可以加個矩形框,但是我覺得沒啥用

theme(text = element_text(size = 20))


把超過顯著性的Pvalue的SNP標(biāo)簽加入。

top <- gwasResults%>% filter(P<=5e-08)

ggplot(gwasResults, aes(SNP1, -log10(P)))+

geom_point(aes(color = CHR), show.legend = FALSE) +

scale_color_manual(values = rainbow(22)) +

geom_hline(yintercept = c(-log10(1e-05), -log10(5e-08)), color = c('blue', 'red'), size = 0.35) +

scale_x_continuous(breaks = chr$location, labels = chr$label, expand = c(0, 0)) +

scale_y_continuous(breaks=seq(1,9,2),labels=as.character(seq(1,9,2)),expand = c(0, 0), limits = c(0, 9)) +

theme(panel.grid = element_blank(), axis.line = element_line(colour = 'black'), panel.background = element_rect(fill = 'transparent')) +

labs(x = 'Chromosome', y = expression(''~-log[10]~'(P)'))+

#annotate('rect', xmin = 0, xmax = max(gwasResults$SNP1), ymin = -log10(1e-05), ymax = -log10(5e-08), fill = 'gray98') +

theme(text = element_text(size = 20))+

geom_label_repel(data=top,aes(x=SNP1, y=-log10(P), label = SNP),size = 4,box.padding = unit(0.5, 'lines'),show.legend = FALSE)

下面我們嘗試用曼哈頓圖畫一個微生物領(lǐng)域常見的圖。

一般情況下,在這種圖中:

散點:代表單個OTU;

散點大小:相對豐度;

散點形狀:顯著富集實心圓點,否則為圓環(huán);

灰色背景:間隔每個目水平(或強調(diào)是否存在顯著富集OTUs);

水平線:顯著性水平p = 0.05;

我們也把上述技巧運用以下,來畫下面這個圖,這個是我們測試數(shù)據(jù)的樣子。


otu_stat <- read.table("otu_sign.txt",header=T,sep="\t")

#先按分類門水平排序,這里直接按首字母排序了,大家也可以按照自己感興趣的順序來排。

otu_stat <- otu_stat[order(otu_stat$phylum), ]

#然后和上面一樣,生成連續(xù)的在X軸上對應(yīng)的坐標(biāo)信息

otu_stat$otu_sort <- 1:nrow(otu_stat)

我們先生成一個最基本的圖。

ggplot(otu_stat, aes(otu_sort, -log10(p_value))) +

geom_point(aes(size = abundance, color = phylum, shape = enrich)) +

scale_size(range = c(1, 5))+

theme_bw()+

scale_shape_manual(values=c("Enriched" = 17, "Depleted" = 25, "Non-signficant" = 20))+ #指定enrich類別的shape

theme(panel.grid = element_blank(), axis.line = element_line(colour = 'black'), panel.background = element_rect(fill = 'transparent'), legend.key = element_rect(fill = 'transparent')) +

labs(x="OTUs", y = expression(~-log[10](P)))


下面我們像上面那個曼哈頓圖一樣手動修改X軸的刻度和注釋。

chr <- aggregate(otu_stat$otu_sort, by = list(otu_stat$phylum ), FUN = median)

colnames(chr) <- c("label","location")

計算每個門類的均值位置,也就是label放的位置。


ggplot(otu_stat, aes(otu_sort, -log10(p_value))) +

geom_point(aes(size = abundance, color = phylum, shape = enrich)) +

scale_x_continuous(breaks = chr$location, labels = chr$label, expand = c(0, 0)) +? #手動添加刻度注釋,在每個門類的均值位置

scale_size(range = c(1, 5))+

theme_bw()+

scale_shape_manual(values=c("Enriched" = 17, "Depleted" = 25, "Non-signficant" = 20))+

theme(panel.grid = element_blank(), axis.line = element_line(colour = 'black'),

? ? ? panel.background = element_rect(fill = 'transparent'),

? ? ? axis.text.x = element_text(angle = 45, hjust = 1),? #調(diào)整X軸坐標(biāo)的角度

? ? ? axis.text = element_text(face = "bold"),

? ? ? legend.key = element_rect(fill = 'transparent')) +

theme(text = element_text(size = 20))+

labs(x="OTUs", y = expression(~-log[10](P)))

ggplot(otu_stat, aes(otu_sort, -log10(p_value))) +

geom_point(aes(size = abundance, color = phylum, shape = enrich)) +

scale_x_continuous(breaks = chr$location, labels = chr$label, expand = c(0, 0)) +

scale_size(range = c(1, 5))+

theme_bw()+

scale_shape_manual(values=c("Enriched" = 17, "Depleted" = 25, "Non-signficant" = 20))+

theme(panel.grid = element_blank(), axis.line = element_line(colour = 'black'),

? ? ? panel.background = element_rect(fill = 'transparent'),

? ? ? axis.text.x = element_text(angle = 45, hjust = 1),

? ? ? axis.text= element_text(face = "bold",size=12),

? ? ? axis.title=element_text(face = "bold",size=15),

? ? ? legend.title = element_text(size = 12),

? ? ? legend.key = element_rect(fill = 'transparent')) +

labs(x = NULL, y = expression(''~-log[10]~'(P)'), size = 'relative abundance (%)', shape = 'significantly enriched') +

guides(color = 'none') +? #把color顯示的legend給去除了,因為已經(jīng)添加X軸坐標(biāo)了

geom_hline(yintercept = c(-log10(1e-05), -log10(5e-08)), color = c('blue', 'red'), size = 1) +

theme(legend.position = 'top', legend.direction = "horizontal")? #調(diào)整legend的位置和方向

我不喜歡添加矩形框,但是如果想要在每個門類那里添加矩形框,也是可以的。我們就要計算矩形框的起始和結(jié)束位置。

其實很簡單,我們只需要獲得每個group中,otu_sort的最大值和最小值即可。比如,舉個例子,我們獲得Acidobacteria數(shù)據(jù)集。

x<- otu_stat %>% filter(phylum=="Acidobacteria")

然后利用min(x$otu_sort),max(x$otu_sort)即可得到最大或者最小值。

p<-ggplot(otu_stat, aes(otu_sort, -log10(p_value))) +

geom_point(aes(size = abundance, color = phylum, shape = enrich)) +

scale_x_continuous(breaks = chr$location, labels = chr$label, expand = c(0, 0)) +

scale_size(range = c(1, 5))+

theme_bw()+

scale_shape_manual(values=c("Enriched" = 17, "Depleted" = 25, "Non-signficant" = 20))+

theme(panel.grid = element_blank(), axis.line = element_line(colour = 'black'),

? ? ? panel.background = element_rect(fill = 'transparent'),

? ? ? axis.text.x = element_text(angle = 45, hjust = 1),

? ? ? axis.text= element_text(face = "bold",size=12),

? ? ? axis.title=element_text(face = "bold",size=15),

? ? ? legend.title = element_text(size = 12),

? ? ? legend.key = element_rect(fill = 'transparent')) +

labs(x = NULL, y = expression(''~-log[10]~'(P)'), size = 'relative abundance (%)', shape = 'significantly enriched') +

guides(color = 'none') +

geom_hline(yintercept = c(-log10(1e-05), -log10(5e-08)), color = c('blue', 'red'), size = 1) +

theme(legend.position = 'top', legend.direction = "horizontal")

把前面的圖保存在p變量中。

p+

annotate('rect', xmin =min(x$otu_sort), xmax=max(x$otu_sort), ymin = -Inf, ymax = Inf, alpha=0.5,

fill ="gray85")

這樣我們就添加了一個灰色框。

接下來,我們寫個for循環(huán)既可以實現(xiàn)。

group <- unique(otu_stat$phylum)

for(i in 1:length(group))

{

? x<- otu_stat %>% filter(phylum==group[i])

? p<- p+annotate('rect', xmin =min(x$otu_sort), xmax=max(x$otu_sort), ymin = -Inf, ymax = Inf, alpha=0.5,

? fill = ifelse(i %% 2 == 0, 'gray95', 'gray85'))

}

p

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容