本文轉載自:Cytoscape可視化物種分類樹結構
Cytoscape可視化物種分類樹結構
。因此本篇就只是概括了一下大致的過程,包括如何準備輸入數據,以及在Cytoscape可視化時大致上要點擊哪些按鈕等,并未仔細琢磨成品圖。所以,下文略顯粗糙,大家有興趣就看吧……
這其實是個物種分類樹,代表的微生物分類。從高級分類水平(界,細菌和真菌)的根節點開始,依次往低分類層級(門綱目科屬等)延伸,逐漸形成分支,末端節點應該是OTU或者種水平。因此,分支呈簇狀展示,分支的顏色主要按門水平著色,將衍生自同一類門的微生物分支賦值相同的顏色。節點的大小應該對應了微生物的豐度,而節點的顏色主要有兩種,猜測紅色代表了一些重要的微生物,白色是不重要的。圖中文字部分則標識了主要的微生物門所含的節點數量,以及這些微生物的總豐度占比。
好吧,其實白魚同學并不知道這是來自哪篇文章的插圖,不清楚它的任何細節,包括其具體的指代信息以及作者試圖表達的意義等,上一段文字純粹是看圖瞎猜的……又懶得問其來源,那就按照這種理解去模仿吧,反正只是隨手畫個圖嘛,不要在意那么多細節。
準備數據
示例數據和預處理R代碼的百度盤鏈接(提取碼,sf9f):
https://pan.baidu.com/s/1nS402FLH3lQu8CNq6JjEsA
網盤附件“otu.txt”如下所示,以OTU的豐度為主,后面跟上這些OTU所屬的界門綱目科屬分類。需要事先把一些注釋不明確的物種提前去除(比如unidentified、unknown、others等),否則導致了一些分類關系混亂。然后將它讀到R中,整合各個分類水平的包含關系,即上一級分類和下一級分類的對應列表用作邊列表,并統計共計多少分類類型及其豐度用作節點列表。
#讀入數據
otu <- read.delim('otu.txt', stringsAsFactors = FALSE, check.names = FALSE)
#整合各分類層級和所含物種豐度的嵌套關系,構建網絡邊列表
#source 和 target 分別對應了上下級物種分類層級的對應關系,abundance 表示 target 的豐度
genus_otu <- otu[c('genus', 'otu', 'abundance')]
names(genus_otu) <- c('source', 'target', 'abundance')
family_genus <- aggregate(otu$abundance, by = list(otu$family, otu$genus), FUN = sum)
names(family_genus) <- c('source', 'target', 'abundance')
order_family <- aggregate(otu$abundance, by = list(otu$order, otu$family), FUN = sum)
names(order_family) <- c('source', 'target', 'abundance')
class_order <- aggregate(otu$abundance, by = list(otu$class, otu$order), FUN = sum)
names(class_order) <- c('source', 'target', 'abundance')
phylum_class <- aggregate(otu$abundance, by = list(otu$phylum, otu$class), FUN = sum)
names(phylum_class) <- c('source', 'target', 'abundance')
kingdom_phylum <- aggregate(otu$abundance, by = list(otu$kingdom, otu$phylum), FUN = sum)
names(kingdom_phylum) <- c('source', 'target', 'abundance')
edge_list <- rbind(kingdom_phylum, phylum_class, class_order, order_family, family_genus, genus_otu)
#將各個分類層級對應至 phylum,以便用于在 Cytoscape 中調整樹分支的顏色
otu_phylum <- otu[c('phylum', 'otu')]
names(otu_phylum)[2] <- 'target'
genus_phylum <- otu[c('phylum', 'genus')]
names(genus_phylum)[2] <- 'target'
family_phylum <- otu[c('phylum', 'family')]
names(family_phylum)[2] <- 'target'
order_phylum <- otu[c('phylum', 'order')]
names(order_phylum)[2] <- 'target'
class_phylum <- otu[c('phylum', 'class')]
names(class_phylum)[2] <- 'target'
phylum_phylum <- otu[c('phylum', 'phylum')]
names(phylum_phylum)[2] <- 'target'
tax_phylum <- rbind(phylum_phylum, class_phylum, order_phylum, family_phylum, genus_phylum, otu_phylum)
tax_phylum <- tax_phylum[!duplicated(tax_phylum$target), ]
edge_list <- merge(edge_list, tax_phylum, by = 'target', all.x = TRUE)
#輸出邊列表
edge_list <- edge_list[c('source', 'target', 'abundance', 'phylum')]
edge_list$weight <- 1
head(edge_list)
write.table(edge_list, 'edge_list.txt', row.names = FALSE, sep = '\t', quote = FALSE)
#構建節點列表,包括各個分類水平的名稱,以及所含物種總豐度等
node_list <- reshape2::melt(otu, id = 'abundance')
node_list <- aggregate(node_list$abundance, by = list(node_list$value, node_list$variable), FUN = sum)
names(node_list) <- c('shared name', 'taxonomy', 'abundance')
#原始豐度 abundance 的數值差較大,不利于直接使用該列在 Cytoscape 中定義節點大小
#再指定個新列 abundance2,對原始的 abundance 作些轉換,比如 log 降低高豐度的權重等
node_list$abundance2 <- log(node_list$abundance+1, 2)? #log 轉化時加個基數 1
#添加節點的 phylum 水平分類
otu_phylum <- otu[c('phylum', 'otu')]
names(otu_phylum)[2] <- 'shared name'
genus_phylum <- otu[c('phylum', 'genus')]
names(genus_phylum)[2] <- 'shared name'
family_phylum <- otu[c('phylum', 'family')]
names(family_phylum)[2] <- 'shared name'
order_phylum <- otu[c('phylum', 'order')]
names(order_phylum)[2] <- 'shared name'
class_phylum <- otu[c('phylum', 'class')]
names(class_phylum)[2] <- 'shared name'
phylum_phylum <- otu[c('phylum', 'phylum')]
names(phylum_phylum)[2] <- 'shared name'
tax_phylum <- rbind(phylum_phylum, class_phylum, order_phylum, family_phylum, genus_phylum, otu_phylum)
tax_phylum <- tax_phylum[!duplicated(tax_phylum$'shared name'), ]
node_list <- merge(node_list, tax_phylum, by = 'shared name', all.x = TRUE)
#根據事先選擇的一些重要節點名稱,在節點列表中標識出后輸出節點列表
select_node <- read.delim('select_node.txt', stringsAsFactors = FALSE)
node_list[which(node_list$'shared name' %in% select_node$id),'select'] <- 1
node_list[which(! node_list$'shared name' %in% select_node$id),'select'] <- 0
head(node_list)
write.table(node_list, 'node_list.txt', row.names = FALSE, sep = '\t', quote = FALSE)
Cytoscape的可視化
這樣兩個輸入文件就準備好了,分別為上述R輸出的“edge_list.txt”和“node_list.txt”,導入至Cytoscape中進行可視化。
1 讀取輸入文件
打開Cytoscape后,點擊“Import Network from File System”讀取邊列表,也就是上述輸出的“edge_list.txt”;以及點擊“Import Table from File”讀取節點列表,“node_list.txt”。
文件導入后,Cytoscape中自動呈現一幅網絡圖,這個網絡圖的結構就代表了給定的物種分類樹了。
2 邊的顏色和尺寸等屬性調整
點擊界面左側“Style”按鈕進入外觀調整選項。首先是對邊的調整,點擊下方“Edge”后進入邊樣式調整界面。
已知該網絡代表了物種分類樹,如上所述,從高級分類水平(界)的根節點開始,依次往低分類層級(門綱目科屬等)延伸,逐漸形成分支。因此,下游的分類分支都衍生自上游高級分類分支。參考圖中將衍生自同一門分類的微生物分支賦值相同的顏色,這里我們效仿,在上文的R操作過程中已經對網絡中每條邊做了歸類,邊列表中的“phylum”列就記錄了分支對應的門分類水平。點擊“Stroke Color”,按邊列表中的“phylum”列分配顏色。
邊的顏色是主要的調節屬性。對于其它的屬性,視情況自定義修改。例如如果覺得邊太細,就可以點擊“Width”將邊的尺寸設置的寬一些,使其更清晰。
3 背景色調整
隨后,點擊下方“Network”,將“Background Paint”背景色設置為黑色。
4 節點的顏色和尺寸等屬性調整
然后是對節點的調整,點擊下方“Node”后進入節點樣式調整界面。
對于節點顏色,點擊“Fill Color”,按節點列表中的“select”列分配顏色,將1(標記的重要的微生物)賦值為紅色,0(不重要的)賦值為白色。
對于節點形狀,勾選下方“Lock node width and height”后,點擊“Shape”統一設置為圓形。
對于節點大小,點擊“Size”,按節點列表中的“abundance2”列指定大小。該列是個連續的數值,大值對應大點,小值對應小點。
以及點擊“Properties”顯示出“Label Transparency”選項后統一設置為0,即將節點標簽均設置為透明,以去除節點標簽。
5 網絡布局調整
上述過程都很簡單,不再多說了,大家看著來設置就行。
最后是調整網絡布局,獲得類似示例圖中的樹狀結構。可以先嘗試一些自動布局,看看哪些布局風格效果較好。下圖展示一些和示例圖較為相似的自動布局,以及一些不相似但是可能有趣的自動布局,供大家參考吧。
點擊菜單欄“Layout”,提供了N種預設布局;此外“Apps”中可以下載更多樣式的插件,例如yFiles布局就是在“Apps”中找的拓展插件之一。
這些自動布局也就是有幾分相似而已。一般來說,網絡圖布局光靠自動布局是難以滿足需求的,配合手工調整肯定是免不了的,只是手工調整的過程會很糟心……哦對了,說不定真的有自動布局能夠出來示例圖樣式,只是沒找到而已
。
以下簡單展示一個手工調節布局的過程。以“Prefuse Force Directed Layout?(按?weight?列定義布局)”布局為例,因為它的微生物節點分類層次不明確,有待手動拖一下。當然,實際情況中盡可能找一個最相似的布局來,這樣可以簡化手動的工作量。點擊“Select”,按微生物節點所屬的門分類水平進行選擇,并將選中的節點拉動至一旁,就可和其它類群分開了。隨后,設法手動選擇節點子集,并拖動將該類群內部的節點的層次結構盡可能區分明顯。
把所有節點的層次關系調整好,將微生物的分類關系較好地呈現出,總之工作量挺大的。所以,白魚同學就沒再繼續,為了一個示例耗費大量時間在里面就不值得了……本篇教程只是作為方法類指引,幫助大家了解大體上是怎樣的操作過程就可以了。真正有需要時,再花點時間配合手工琢磨布局,再慢1天也能搞定了吧。
6 關于文字圖例的添加
最后,如果在Cytoscape中調試出了想要的結果,點擊“File > Export > Network to Image”將圖片導出為pdf矢量圖后,放在AI(Adobe Illustrator)中補充文字標簽。例如示例圖中,微生物門水平的名稱、節點數量和所含物種的豐度占比等,就可以通過AI補充。