R | ggpairs -- 可視化相關(guān)性

最近想要可視化樣本間的相關(guān)性,但又不滿足于常規(guī)的相關(guān)性熱圖状蜗。因此嗓奢,就注意到GGally包中的ggpairs函數(shù),可以方便地實現(xiàn)多方面的相關(guān)性可視化燎窘。

本文僅介紹ggpairs 在連續(xù)型變量方面的應(yīng)用摹闽。它也可以用到離散型變量的可視化上。

下面以airway數(shù)據(jù)集進行演示:
這里我們在前4個樣本中隨機選取1000個基因進行展示

library(GGally)
# airway example
library(airway)
data(airway)
df <- as.data.frame(assays(airway)$counts[,1:4]) #first 4 columns
df <- df[rowSums(df)>4,] #keep genes with some counts
set.seed(123)
df <- df[sample.int(nrow(df),1e3),] #random 1K gene
# ggpairs default
ggpairs(log2(df+1))

ggpairs將輸出的圖劃分為三個區(qū)域褐健,分別是左下角的lower, 對角線的diag, 以及右上角的upper. 對于連續(xù)性數(shù)值變量付鹿,默認(rèn)在lower區(qū)畫pairwise scatter plot,diag區(qū)畫density plot铝量,upper區(qū)展示相應(yīng)的pairwise Pearson's correaltion coefficient.

進一步倘屹,我還希望在左下角的散點圖中加入y=x的擬合線,并在對角線的加上直方圖慢叨。我們可以通過自定義畫圖的函數(shù)實現(xiàn)這些操作纽匙。

ggscatter <- function(data, mapping, ...) {
  x <- GGally::eval_data_col(data, mapping$x)
  y <- GGally::eval_data_col(data, mapping$y)
  df <- data.frame(x = x, y = y)
  sp1 <- ggplot(df, aes(x=x, y=y)) +
    geom_point() +
    geom_abline(intercept = 0, slope = 1, col = 'darkred')
  return(sp1)
}

ggdehist <- function(data, mapping, ...) {
  x <- GGally::eval_data_col(data, mapping$x)
  df <- data.frame(x = x)
  dh1 <- ggplot(df, aes(x=x)) +
    geom_histogram(aes(y=..density..), bins = 50, fill = 'steelblue', color='black', alpha=.4) +
    geom_density(aes(y=..density..)) + 
    theme_minimal()
  return(dh1)
}

ggpairs(log2(df+1),
        lower = list(continuous = wrap(ggscatter)),
        diag = list(continuous = wrap(ggdehist))) + 
  theme_minimal() +
  theme(panel.grid = element_blank(),
        panel.border = element_rect(fill=NA),
        axis.text =  element_text(color='black'))

再放一個高度修改的版本

# https://pascal-martin.netlify.app/post/nicer-scatterplot-in-gggally/
GGscatterPlot <- function(data, mapping, ..., 
                          method = "pearson") {
  
  #Get correlation coefficient
  x <- GGally::eval_data_col(data, mapping$x)
  y <- GGally::eval_data_col(data, mapping$y)
  
  cor <- cor(x, y, method = method, use="pairwise.complete.obs")
  #Assemble data frame
  df <- data.frame(x = x, y = y)
  df <- na.omit(df)
  # PCA
  nonNull <- x!=0 & y!=0
  dfpc <- prcomp(~x+y, df[nonNull,])
  df$cols <- predict(dfpc, df)[,1]
  # Define the direction of color range based on PC1 orientation:
  dfsum <- x+y
  colDirection <- ifelse(dfsum[which.max(df$cols)] < 
                           dfsum[which.min(df$cols)],
                         1,
                         -1)
  #Get 2D density for alpha
  dens2D <- MASS::kde2d(df$x, df$y)
  df$density <- fields::interp.surface(dens2D ,df[,c("x", "y")])
  
  if (any(df$density==0)) {
    mini2D = min(df$density[df$density!=0]) #smallest non zero value
    df$density[df$density==0] <- mini2D
  }
  #Prepare plot
  pp <- ggplot(df, aes(x=x, y=y, alpha = 1/density, color = cols)) +
    ggplot2::geom_point(shape=16, show.legend = FALSE) +
    ggplot2::scale_color_viridis_c(direction = colDirection) +
    ggplot2::scale_alpha(range = c(.05, .6)) +
    ggplot2::geom_abline(intercept = 0, slope = 1, col="darkred") +
    ggplot2::geom_label(
      data = data.frame(
        xlabel = min(x, na.rm = TRUE),
        ylabel = max(y, na.rm = TRUE),
        lab = round(cor, digits = 3)),
      mapping = ggplot2::aes(x = xlabel,
                             y = ylabel,
                             label = lab),
      hjust = 0, vjust = 1,
      size = 3, fontface = "bold",
      inherit.aes = FALSE # do not inherit anything from the ...
    ) +
    theme_bw()
  return(pp)
}

exonNumber <- elementNROWS(rowRanges(airway[rownames(df),]))
df$MoreThan15Exons <- ifelse(exonNumber>15,
                             ">15ex", "<15ex")
df[,1:4] <- log2(df[,1:4]+1)
GGally::ggpairs(df,
                1:4,
                lower = list(continuous = wrap(GGscatterPlot, method="pearson")),
                upper = list(continuous = wrap(ggally_cor, align_percent = 0.8), 
                             mapping = ggplot2::aes(color = MoreThan15Exons))) +
  theme_minimal() +
  theme(panel.grid = element_blank(),
        panel.border = element_rect(fill=NA),
        axis.text =  element_text(color='black'))

  • 對散點圖的透明度進行調(diào)整,點越密的區(qū)域透明度越高拍谐,反之亦然烛缔。
  • 散點圖的顏色代表了基因表達量。
  • 在散點圖左上角添加Pearson's 相關(guān)系數(shù)
  • 右上角展示了對小于15個外顯子的基因和大于15個外顯子基因的相關(guān)性的統(tǒng)計轩拨。

在我看來ggpairs相當(dāng)于是一個ggplot2的集成可視化方法践瓷,可以很方便的一次性展示多個方面的相關(guān)性信息。同時亡蓉,它的可定制性也很高晕翠,可以滿足許多額外的可視化需求。唯一的缺陷可能是需要耗費一定功夫?qū)懗霭b的函數(shù)砍濒。

ref
ggpairs doc: https://ggobi.github.io/ggally/articles/ggpairs.html
Nicer scatter plots in GGgally ggpairs-ggduo: https://pascal-martin.netlify.app/post/nicer-scatterplot-in-gggally
Creating a density histogram in ggplot2: https://stackoverflow.com/questions/21061653/creating-a-density-histogram-in-ggplot2

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淋肾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子爸邢,更是在濱河造成了極大的恐慌樊卓,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杠河,死亡現(xiàn)場離奇詭異碌尔,居然都是意外死亡浇辜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門唾戚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柳洋,“玉大人,你說我怎么就攤上這事叹坦∩旁睿” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵立由,是天一觀的道長轧钓。 經(jīng)常有香客問我,道長锐膜,這世上最難降的妖魔是什么毕箍? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮道盏,結(jié)果婚禮上而柑,老公的妹妹穿的比我還像新娘。我一直安慰自己荷逞,他們只是感情好媒咳,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著种远,像睡著了一般涩澡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坠敷,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天妙同,我揣著相機與錄音,去河邊找鬼膝迎。 笑死粥帚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的限次。 我是一名探鬼主播芒涡,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼卖漫!你這毒婦竟也來了费尽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤懊亡,失蹤者是張志新(化名)和其女友劉穎依啰,沒想到半個月后乎串,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體店枣,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡速警,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鸯两。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闷旧。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钧唐,靈堂內(nèi)的尸體忽然破棺而出忙灼,到底是詐尸還是另有隱情,我是刑警寧澤钝侠,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布该园,位于F島的核電站,受9級特大地震影響帅韧,放射性物質(zhì)發(fā)生泄漏里初。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一忽舟、第九天 我趴在偏房一處隱蔽的房頂上張望双妨。 院中可真熱鬧,春花似錦叮阅、人聲如沸刁品。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挑随。三九已至,卻和暖如春勒叠,著一層夾襖步出監(jiān)牢的瞬間镀裤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工缴饭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留暑劝,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓颗搂,卻偏偏與公主長得像担猛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丢氢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容