改进Python NetworkX图形布局

Say*_*yan 31 python networkx

我在使用python-networkx创建的图形可视化方面存在一些问题,我希望能够减少混乱并调节节点之间的距离(我还尝试过spring_layout,它只是以椭圆形方式布置节点).请指教. 在此输入图像描述

部分代码:

nx.draw_networkx_edges(G, pos, edgelist=predges, edge_color='red', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False, style='dashed')
# label fonts
nx.draw_networkx_labels(G,pos,font_size=7,font_family='sans-serif')
nx.draw_networkx_edge_labels(G,pos,q_list,label_pos=0.3)
Run Code Online (Sandbox Code Playgroud)

Hoo*_*ked 48

在networkx中,值得查看graphviz via 提供的图形绘制算法nx.graphviz_layout.

我取得了很大的成功,neato但其他可能的投入是

  • dot - 有向图的"分层"或分层图.如果边具有方向性,则这是默认工具.

  • neato - "弹簧模型"布局.如果图形不是太大(大约100个节点),这是默认工具,你不知道其他任何东西.内托尝试最小化全局能量函数,这是等价的统计多维缩放.

  • fdp - "弹簧模型"的布局类似于neato,但这是通过减少力而不是使用能量来实现的.

  • sfdp - 用于大图形布局的fdp的多尺度版本.

  • twopi - Graham Wills 97之后的径向布局.节点根据与给定根节点的距离放置在同心圆上.

  • circo - 在Six和Tollis 99,Kauffman和Wiese 02之后的圆形布局.这适用于多个循环结构的某些图,例如某些电信网络.

通常,图形绘制是一个难题.如果这些算法不够,您必须自己编写或单独使用networkx绘制零件.

  • 用法:`nx.draw(G,pos = graphviz_layout(G))` (4认同)
  • 添加到@DiCaprio,首先安装pygraphviz:`pip install pygraphviz`然后`nx.draw(G, pos=nx.nx_agraph.graphviz_layout(G))` (3认同)
  • 对于`graphviz_layout`的问题,请参阅http://stackoverflow.com/questions/35279733/what-c​​ould-cause-networkx-pygraphviz-to-work-fine-alone-but-not-together (2认同)

Vic*_*art 7

我发现这对于快速可视化来自PostgreSQL的CSV文件的交互数据很有用。[为便于阅读,下面的格式重新格式化。]

## PSQL ['DUMMY' DATA]:

[interactions_practice]# \copy (SELECT gene_1, gene_2 FROM interactions
  WHERE gene_1 in (SELECT gene_2 FROM interactions))
  TO '/tmp/a.csv' WITH CSV      -- << note: no terminating ";" for this query

## BASH:

[victoria@victoria ~]$ cat /tmp/a.csv                                                                                                      

  APC,TP73
  BARD1,BRCA1
  BARD1,ESR1
  BARD1,KRAS2
  BARD1,SLC22A18
  BARD1,TP53
  BRCA1,BRCA2
  BRCA1,CHEK2
  BRCA1,MLH1
  BRCA1,PHB
  BRCA2,CHEK2
  BRCA2,TP53
  CASP8,ESR1
  CASP8,KRAS2
  CASP8,PIK3CA
  CASP8,SLC22A18
  CDK2,CDKN1A
  CHEK2,CDK2
  ESR1,BRCA1
  ESR1,KRAS2
  ESR1,PPM1D
  ESR1,SLC22A18
  KRAS2,BRCA1
  MLH1,CHEK2
  MLH1,PMS2
  PIK3CA,BRCA1
  PIK3CA,ESR1
  PIK3CA,RB1CC1
  PIK3CA,SLC22A18
  PMS2,TP53
  PTEN,BRCA1
  PTEN,MLH3
  RAD51,BRCA1
  RB1CC1,SLC22A18
  SLC22A18,BRCA1
  TP53,PTEN


## PYTHON 3.5 VENV (ANACONDA):

>>> import networkx as nx
>>> import pylab as plt
>>> G = nx.read_edgelist("/tmp/a.csv", delimiter=",")

>>> G.edges()

  [('CDKN1A', 'CDK2'), ('MLH3', 'PTEN'), ('TP73', 'APC'), ('CHEK2', 'MLH1'),
   ('CHEK2', 'BRCA2'), ('CHEK2', 'CDK2'), ('CHEK2', 'BRCA1'), ('BRCA2', 'TP53'),
   ('BRCA2', 'BRCA1'), ('KRAS2', 'CASP8'), ('KRAS2', 'ESR1'), ('KRAS2', 'BRCA1'),
   ('KRAS2', 'BARD1'), ('PPM1D', 'ESR1'), ('BRCA1', 'PHB'), ('BRCA1', 'ESR1'),
   ('BRCA1', 'PIK3CA'), ('BRCA1', 'PTEN'), ('BRCA1', 'MLH1'), ('BRCA1', 'SLC22A18'),
   ('BRCA1', 'BARD1'), ('BRCA1', 'RAD51'), ('CASP8', 'ESR1'), ('CASP8', 'SLC22A18'),
   ('CASP8', 'PIK3CA'), ('TP53', 'PMS2'), ('TP53', 'PTEN'), ('TP53', 'BARD1'),
   ('PMS2', 'MLH1'), ('PIK3CA', 'SLC22A18'), ('PIK3CA', 'ESR1'), ('PIK3CA', 'RB1CC1'),
   ('SLC22A18', 'ESR1'), ('SLC22A18', 'RB1CC1'), ('SLC22A18', 'BARD1'), ('BARD1', 'ESR1')]

>>> G.number_of_edges()
  36

>>> G.nodes()

  ['CDKN1A', 'MLH3', 'TP73', 'CHEK2', 'BRCA2', 'KRAS2', 'CDK2', 'PPM1D', 'BRCA1',
   'CASP8', 'TP53', 'PMS2', 'RAD51', 'PIK3CA', 'MLH1', 'SLC22A18', 'BARD1', 'PHB', 'APC', 'ESR1', 'RB1CC1', 'PTEN']

>>> G.number_of_nodes()
  22

>>> from networkx.drawing.nx_agraph import graphviz_layout

>>> ## nx.draw(G, pos=graphviz_layout(G))

## DUE TO AN UNIDENTIFIED BUG, I GET THIS ERROR THE FIRST TIME RUNNING THIS
## COMMAND; JUST RE-RUN IT:

>>> nx.draw(G, pos=graphviz_layout(G), node_size=1200, node_color='lightblue',
    linewidths=0.25, font_size=10, font_weight='bold', with_labels=True)

  QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries.

>>> nx.draw(G, pos=graphviz_layout(G), node_size=1200, node_color='lightblue',
    linewidths=0.25, font_size=10, font_weight='bold', with_labels=True)

>>> plt.show()    ## plot1.png [opens in matplotlib popup window] attached
Run Code Online (Sandbox Code Playgroud)

在这些静态networkx / matplotlib图中,很难减少拥塞。一种解决方法是,根据以下StackOverflow问题,增加图形大小:使用NetworkX和Matplotlib的图形的高分辨率图像

>>> plt.figure(figsize=(20,14))
  <matplotlib.figure.Figure object at 0x7f1b65ea5e80>

>>> nx.draw(G, pos=graphviz_layout(G), node_size=1200, node_color='lightblue',
    linewidths=0.25, font_size=10, font_weight='bold', with_labels=True, dpi=1000)

>>> plt.show()    ## plot2.png attached

## RESET OUTPUT FIGURE SIZE TO SYSTEM DEFAULT:

>>> plt.figure()
  <matplotlib.figure.Figure object at 0x7f1b454f1588>
Run Code Online (Sandbox Code Playgroud)

plot1.png plot1.png

plot2.png plot2.png

奖金-最短路径:

>>> nx.dijkstra_path(G, 'CDKN1A', 'MLH3')
['CDKN1A', 'CDK2', 'CHEK2', 'BRCA1', 'PTEN', 'MLH3']
Run Code Online (Sandbox Code Playgroud)

  • 妈妈,你是英雄。特别是,此答案中 `.draw` 中的选项文档超过了实际的 `networkx` 文档,IMO 中的类似文档。 (2认同)
  • @MaxvonHippel:你评论中的喜悦超过了我对这个答案的任何支持!;-) (2认同)

phy*_*rox 5

您的图表中有大量数据,因此很难消除混乱.

我建议你使用任何标准布局.你说你用过spring_layout.我建议你再试一次,但这次是weight在添加边缘时使用属性.

例如:

import networkx as nx

G = nx.Graph();
G.add_node('A')
G.add_node('B')
G.add_node('C')
G.add_node('D')
G.add_edge('A','B',weight=1)
G.add_edge('C','B',weight=1)
G.add_edge('B','D',weight=30)

pos = nx.spring_layout(G,scale=2)

nx.draw(G,pos,font_size=8)
plt.show()
Run Code Online (Sandbox Code Playgroud)

此外,您可以使用该参数scale来增加节点之间的全局距离.

  • 权重如何影响算法?权重越高==节点越近,还是反之亦然? (2认同)