R

networkx + Cytoscape 构建及可视化网络图

2019-06-21  本文已影响55人  GPZ_Lab

本次笔记内容:

  • 网络图的简要结构
  • 以相关系数表为例:networkx构建网络结构
  • Cytoscape可视化网络图
网络图的简要结构

网络结构由点及连接点的线组成,反映了点所代表的元素之间的关系。网络图使得我们对各元素之间的关系有一个直接的认识。比方说如果每个元素是一个OTU,

以相关系数表为例network绘制网络图

这里用的networkx是Python一个模块。我们用它来定义构成网络图的点,线,及点线的各种属性。
安装networkx : $ pip install networkx

以下为一个基础示例,可以快速了解一下:

import networkx as nx
import matplotlib.pylab as plt
G = nx.Graph()   # 生成一个空的network对象

G.add_node('a',group='t1', your_group='your_group1' )  # 添加每个点(node), group就是node的类别属性,你可以自定义每个node的属性。
G.add_node('b',group='t1', ) 
G.add_node('c',group='t2')  
print(G.node(data=True))
# 点以list储存,是有顺序的,其属性以字典储存。
# [('a', {'group': 't1', 'your_group': 'your_group1'}), ('b', {'group': 't1'}), ('c', {'group': 't2'})]

G.add_edge('a', 'b', weight=0.5,graphics={'fill' : '#CD5C5C'}) # 添加边,a,b两点之间的连线weight为0.5,填充颜色为#CD5C5C
print(G.edge(data=True))
# [('a', 'b', {'weight': 0.5, 'graphics': {'fill': '#CD5C5C'}})]
# 注意以上network各属性的存储方式,可以通过for循环来批量设置点和线的属性。

node_color = ['yellow','yellow','orange']
nx.draw(G,node_color=node_color,node_size=200, with_labels=True)
plt.show()
# 可以结合matplotlib在python里可视化

nx.write_gml(G, 'XXX.gml')
# 网络结构可以存储为.gml等格式,作为Cytoscape的input
# 另外,gml格式不允许类别名称出现下划线‘_’,即group不可以是group_a这样的写法。

以下以sklearn中 wine recognition dataset为例,
先构建相关系数矩阵:

import networkx as nx
import matplotlib.pylab as plt
from sklearn import datasets
import pandas as pd
from scipy.stats.stats import pearsonr  # 用来计算pearson相关系数

wine_data = datasets.load_wine()
wine_df = pd.DataFrame(data=wine_data['data'],columns=wine_data['feature_names'])
wine_df.head() # 行为samples, 列为features
> alcohol   malic_acid  ash alcalinity_of_ash   magnesium   total_phenols   flavanoids  nonflavanoid_phenols    proanthocyanins color_intensity hue od280/od315_of_diluted_wines    proline 
0   14.23   1.71    2.43    15.6    127.0   2.80    3.06    0.28    2.29    5.64    1.04    3.92    1065.0  
1   13.20   1.78    2.14    11.2    100.0   2.65    2.76    0.26    1.28    4.38    1.05    3.40    1050.0  
2   13.16   2.36    2.67    18.6    101.0   2.80    3.24    0.30    2.81    5.68    1.03    3.17    1185.0  
3   14.37   1.95    2.50    16.8    113.0   3.85    3.49    0.24    2.18    7.80    0.86    3.45    1480.0  
4   13.24   2.59    2.87    21.0    118.0   2.80    2.69    0.39    1.82    4.32    1.04    2.93    735.0   

corr = pd.DataFrame()
corr_p = pd.DataFrame()
for i in wine_df.columns:
    for j in wine_df.columns:
        corr.loc[i,j] = pearsonr(wine_df[i], wine_df[j])[0]
        corr_p.loc[i,j] = pearsonr(wine_df[i], wine_df[j])[1]
corr.head() # 是一个wine_df.columns对wine_df.columns的对称table

tep = abs(corr_p.values) < 0.05
temp.sum()   # 135,p<0.05的不少

然后构建网络结构:

def dataframe_to_tp(corr, row, corr_pvalue):
   '''
   :param corr: corr df
   :param row: like "alcohol" (single OTU index, for loop use)
   :param corr_pvalue: corr_p df
   :return: row_list: [('alcohol','ash', cor('alcohol','ash'))]
   很冗余,能写的更elegent请告诉我
   '''
   row_list = []
   for col in list(corr.columns):
       if (corr_pvalue.loc[row, col] < 0.05) & (abs(corr).loc[row,col] > 0.5):
           tp = (row, col, corr.loc[row, col])
           row_list.append(tp)
       else:
           pass
   for i in row_list:
       if i[0] == i[1]: # 把那些自己对自己的去掉
           row_list.remove(i)
   return row_list

print(dataframe_to_tp(corr, 'alcohol',corr_p))
# [('alcohol', 'color_intensity', 0.5463641950837036), ('alcohol', 'proline', 0.6437200371782135)]

weighted_edges_list = [] # tuple list: [(node1,node2,weight),(...),()]
for row in corr.index.values:
    weighted_edges_list += dataframe_to_tp(corr, row, corr_p)

# 把做好的tuple list用于构建网络:
G = nx.Graph()
# G.add_weighted_edges_from(weighted_edges_list)  这样也可以
for tp in weighted_edges_list:
    node1 = tp[0]
    node2 = tp[1]
    weight = tp[2]
    if weight > 0:   # 给正负相关系数添上不同的颜色
        G.add_edge(node1, node2, weight=abs(weight), graphics={'fill':'#CD5C5C'})
    else:
        G.add_edge(node1, node2, weight=abs(weight), graphics={'fill':'#4682B4'})

# 画图
edge_width = [G[u][v]['weight']*10 for u,v in G.edges()]
color = [G[u][v]['graphics']['fill'] for u,v in G.edges()]
nx.draw(G,width=edge_width, pos = nx.circular_layout(G), edge_color=color, with_labels=True)
# 如下图所示

nx.write_gml(G, 'XXX/wine.gml')
# wine.gml就是网络结构了,接下来把它导入Cytoscape可视化

线的粗细为相关系数的大小(不太明显,因为相关系数差不多),红色为正相关,蓝色为负相关。networkx确实也可以很好的可视化网络图,但Cytoscape的功能更完备。

Cytoscape可视化网络图

Cytoscape是一个免费软件,可以在win,macOS及Linux系统上使用。其下载和安装对java有要求,可以参考其官网下载指南

安装好Cytoscape后,打开并导入(import)上述构建的.gml格式网络结构:

得到:

设置layout : layout是用算法将网络的形态改变,调整成合适的样子。以下为两种不同layout的效果。可以看到我们在Python里设置的edges颜色在这里出现了。
Control Panel中Style栏用于设置字体大小,node框性状及颜色,如果node有分组信息可以按组批量设置。建议自己都点着试试,很容易上手。
Table Panel中包括node table, edge table和network table。
一篇超级详细的Cytoscape中文攻略可以参考。

按照weight的大小定义线的width,注意在style的edge栏里设置。

在style里还可以设置网络图的appearance:

导出为pdf:

最后跑个题,安利一下Atom, 一个text editor. 在win上用的话可以扔掉Notepad++了。而且我感觉没用到很高级的功能的话,pycharm都可以扔掉了...R, python, js等各种语言的代码都可以往里塞,可以自行下载海量packages来满足五花八门的需求,界面如下:

像ipython一样逐行输出:


图也可以plot出来,在代表颜色的字符串上直接print出颜色(太炫了!!看这个Q萌的界面!颜控爱了!!(´Д` ))

参考:
networkx官方tutorial
network.draw的细节
一篇超级详细的Cytoscape中文攻略
Cytoscape tutorials官网
知乎专栏上一个atom的介绍
Atom官方使用指南

上一篇下一篇

猜你喜欢

热点阅读