如何用python实现网络图节点权重的添加以及如何把一个非连通的大网络图分成多个小网络图

Python014

如何用python实现网络图节点权重的添加以及如何把一个非连通的大网络图分成多个小网络图,第1张

networkx是python的一个库,它为图的数据结构提供算法、生成器以及画图工具。近日在使用ryu进行最短路径获取,可以通过该库来简化工作量。该库采用函数方式进行调用相应的api,其参数类型通常为图对象。函数API的调用,按照以下步骤来创建构建图:1.networkx的加载在python中调用networkx通常只需要将该库导入即可import networkx as nx2.图对象的创建networkx提供了四种基本图对象:Graph,DiGraph,MultiGraph,MultiDiGraph。使用如下调用方式,可以创建以上四种图对象的空图。G=nx.Graph()G=nx.DiGraph()G=nx.MultiGraph()G=nx.MultiDiGraph()在 networkx中,图的各个节点允许以哈希表对象来表示,而对于图中边的各个参量,则可以通过与边相关联的方式来标识,一般而言,对于权重,用weight作为keyword,而对于其他的参数,使用者可以采用任何除weight以外的keyword来命名。3.在2中,创建的只是一副空图,为了得到一个有节点、有边的图,一般采用下面这个函数:12G.add_edge(1,2) #default edge data=1G.add_edge(1,2) #specify edge data=0.9add_edge()函数,该函数在调用时需要传入两个参数u和v,以及多个可选参数u和v即图中的两个节点,如果图中不存在节点,在调用时会自动将这两个节点添加入内,同时构建两个节点之间的连接关系,可选参数通常指这条边的权重等关系参量。需要注意的是,如果图中已经存在了这条边,重新进行添加时会对这条边进行跟新操作(也就是覆盖了原有的信息)。对于该函数,除了上述的构建方式以外,还有以下几种方式来创建边:123G.add_edge(*e) # single edge as tuple of two nodesG.add_edge(1, 3, weight=7, capacity=15, length=342.7) #using many arguements to create edgeG.add_edges_from( [(1, 2)] ) # add edges from iterable container有时候,当采用默认方式创建边以后,我们可能还会往边里面添加边的相关参数,这时候,可以采用下面的方式来更新边的信息:12345#For non-string attribute keys, use subscript notation.G.add_edge(1, 2)G[1][2].update({0: 5}) #更新边的信息G.edges[1, 2].update({0: 5}) #更新边的信息#上述两种更新方式,择一选取即可细心的朋友可能注意到我在写创建图的内容的时候,提到了add_edges_from()函数,该函数也是用来创建边的,该方式与add_edges()略有不同,比之add_edges()采用一个一个节点的方式进行创建,它来的更为便利。这个函数在调用时,需要一个节点元组作为参数以及多个可选参数作为边的信息。你可以这么传递:默认创建节点之间的边:1G.add_edges_from([(u,v)]) 也可以这么写,在创建的同时添加信息:1G.add_edges_from([(3, 4), (1, 4)], label='WN2898') 通过上述方式,就构建了一个3-4-1的图的连接,并给每条边打上了标签。由此你就可以创建出自己的图模型了。

用Python实现Circos图的绘制在线绘制的Circos有一定局限性,如对数据的要求、个性化的局限和处理速度等的问题,但如果你是一个Pythoneer或者喜欢用更加Pythonic的方式来个性化地绘制Circos图,那么今天就跟随我一起用代码实现这一目标吧!

安装Circos包

首先,登录Python的包索引网站Python Package Index(PyPI,正确读音是:Pie Pee Ai),找到Circos包的下载页:

https://pypi.python.org/pypi/Circos/1.3.5

该包/模块的作者是我的好友Eric Ma。你可以选择下载wheeler文件,然后本地安装。也可以在shell下直接通过pip进行安装:

pipinstallcircos

注意,所支持的Python版本必须是3.x,对2不支持。

选择数据

当安装了circos包后,我们就可以直接应用这个包来写代码了。为了演示方便,我需要应用一些数据。作为内科医师,就让我来展示一下老本行:处理药物与肝酶细胞色素P450的相互关系的可视化。由于是为了抛砖引玉,所以绘制出的Circos图相对简单。

我们先从美国FDA官网下载不同细胞色素相关的各种口服药物表。共202种常用的口服药物,涵盖内科学、肿瘤学、神经科和心理学等学科。数据文件如下:

可以看到这个数据的结构:是按肝细胞色素酶进行分类,共分8个列。这8个细胞色素酶分别是:CYP1A2,CYP2B6, CYP2C8, CYP2C9, CYP2C19, CYP2D6, CYP2E1和CYP3A4。我们将要建立各个口服药与这些肝酶之间关系的Circos图,从而了解通过相同肝酶代谢或转化的药物之间是否存在相互作用。

导入各个模块和读入数据

导入各个模块:

fromcircosimportCircosPlot

importxlrd

importpandasaspd

importnumpyasnp

读入文件:

filename='.\\MedicationInteraction.xlsx'

book=xlrd.open_workbook(filename)

print('File loaded!')

提取数据:

nrows=book.sheet_by_name('Sheet1').nrows

header=book.sheet_by_name('Sheet1').row_values(0)

data=[book.sheet_by_name('Sheet1').row_values(i) fori inrange(1, nrows)]

df=pd.DataFrame(data, columns =header)

df[df==''] = np.nan

读取后,药物和酶的数据为pandas的DataFrame数据结构,细胞色素P450酶的名字为columns的名字。我们可以检查一下数据:

修数据,尤其是处理NA数据

df_dict={}

foriinrange(len(df.columns)):

df_dict[df.icol(i).name] =list(df.icol(i).dropna())

节点和连线

创建节点(nodes)数据,在我这个例子里就是各个药物和肝酶:

nodes=[]

forkeyindf_dict.keys():

nodes.extend(df_dict[key])

nodes=list(nodes)

headers=list(df.columns)

enzymes=['0'] * 5

forheaderinheaders:

enzymes.append(header)

enzymes.extend(['0']*5)

nodes.extend(enzymes)

创建连线(edges)数据,我们应用tuple(元组)这个数据结构来表示药物与特定肝酶之间的关系:

edges_origin=[]

forkeyindf_dict.keys():

forvalue indf_dict[key]:

edges_origin.append((key, value))

绘图

绘制Circos图:

c=CircosPlot(nodes, edges_origin, radius =10,

nodecolor="blue",

edgecolor="red",

)

c.draw()

得到了下面这张所有药物与肝酶之间的图:

左上方是8个肝脏细胞色素P450酶(CYP1A2、CYP2B6、CYP2C8、CYP2C9、CYP2C19、CYP2D6、CYP2E1和CYP3A4)。其它点即为202种口服药物。每种药物都与参与代谢和转化它的P450酶相连。与相同酶连接的不同药物,理论上应该都存在相互作用,但具体如何还要看与酶的作用机理。

个性化绘图

如果我们打算分别可视化出不同肝酶的关系图形,我们只需改变连线信息,即edges信息:

edges=[]

&#8205forvalueindf_dict['CYP2B6']:

edges.append(('CYP2B6', value))

c=CircosPlot(nodes, edges, radius =10,

nodecolor="orange",

edgecolor="orange",

)

c.draw()

从而我们得到了各种肝酶所代谢和转化药物的图形

用PS将它们合并:

相同肝酶所代谢和转化的药物用相同颜色的edges表示。

显示特定药物

最后,我们可以挑选其中一些感兴趣的药物来进行观察,例如,我从这202个药物中指定几个我感兴趣的药物:

propafenone(心律平), acetaminophen(对乙酰氨基酚), paclitaxel(紫杉醇), ibuprofen(布洛芬), losartan(洛沙坦), omeprazole(奥美拉唑), carvediolo(卡维地洛), codeine(可待因), theophylline(茶碱), quinidine(奎尼丁), verapamil(异搏定), lovastatin(洛伐他汀), nitrendipine(尼群地平)

然后重新建立edges:

medications=['propafenone', 'acetaminophen', 'paclitaxel', 'ibuprofen', 'losartan', 'omeprazole', 'carvedilol', 'codeine', 'theophylline', 'quinidine', 'verapamil', 'lovastatin', 'nitrendipine']

edges_candidate=set()

formedicationinmedications:

foredge inedges_origin:

if medication==edge[1]:

edges_candidate.add(edge)

edges_candidate=list(edges_candidate)

然后再绘图:

c=CircosPlot(nodes, edges_candidate, radius =10,

nodecolor="black",

edgecolor="black",

)

c.draw()

从而得到这张图。

1)首先Python画图与WING IDE无关,最简单的是使用Tkinter画图

2)画出单词有很多方法,最笨的是用划线方式一笔一笔的画。其次是直接输出文本,但意义不大。另外一种方法是调用图片,你可以在图片上任意画好东西后显示出来。

3)代码示例:(这个例子就画了个简单的字母P)

from Tkinter import *

root=Tk()

root.title('Drawing Example')

canvas=Canvas(root,width=200,height=160,bg='white')

canvas.create_line(10,10,100,70)

canvas.create_line(10,10,40,10)

canvas.create_line(40,10,40,40)

canvas.create_line(10,40,40,40)

canvas.pack()

root.mainloop()