Cytoscape可视化物种分类树结构

本文转载自: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补充。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容