web-dev-qa-db-ja.com

Python NetworkXグラフレイアウトの改善

私はpython-networkxで作成されたグラフを視覚化する際にいくつかの問題があります。混乱を減らし、ノード間の距離を調整できるようにしたいと思います(spring_layoutも試しましたが、ノードを楕円形にレイアウトしているだけです)。お知らせ下さい。 enter image description here

コードの一部:

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)
29
Sayan

Networkxでは、- graphviz を介して nx.graphviz_layout で提供されるグラフ描画アルゴリズムを確認する価値があります。

私はneatoで大成功を収めましたが、他の可能な入力は

  • dot-有向グラフの「階層」または階層化された図面。これは、エッジに方向性がある場合に使用するデフォルトのツールです。

  • neato-「スプリングモデル」レイアウト:これは、グラフが大きすぎず(約100ノード)、他に何も知らない場合に使用するデフォルトのツールです。エネルギー関数。これは、統計的な多次元スケーリングに相当します。

  • fdp-neatoのレイアウトに似た「スプリングモデル」レイアウトですが、エネルギーを使用するのではなく力を減らすことでこれを行います。

  • sfdp-大きなグラフのレイアウト用のfdpのマルチスケールバージョン。

  • twopi-Graham Wills 97以降の放射状レイアウト。ノードは、指定されたルートノードからの距離に応じて同心円上に配置されます。

  • circo-Six and Tollis 99、Kauffman and Wiese 02の後の円形レイアウト。これは、特定の通信ネットワークなど、複数の周期構造の特定の図に適しています。

一般的に、 グラフ描画 は難しい問題です。これらのアルゴリズムが十分でない場合は、独自に作成するか、networkxに個別にパーツを描画させる必要があります。

46
Hooked

これは、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

これらの静的networkx/matplotlibプロットの輻輳を減らすことは困難です。回避策の1つは、このStackOverflowのQ/Aに従って図のサイズを増やすことです。 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>

plot1.pngplot1.png

plot2.pngplot2.png

ボーナス-最短経路:

>>> nx.dijkstra_path(G, 'CDKN1A', 'MLH3')
['CDKN1A', 'CDK2', 'CHEK2', 'BRCA1', 'PTEN', 'MLH3']
6
Victoria Stuart

グラフには大量のデータがあるため、混乱を取り除くのは難しいでしょう。

標準レイアウトを使用することをお勧めします。あなたは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()

さらに、パラメータscaleを使用して、ノード間のグローバル距離を増やすことができます。

5
phyrox

ノード間の距離を調整する方法についての質問に答えるために、 フックの答え を展開します。

Graphvizバックエンドを介してグラフを描画し、fdpアルゴリズムを使用する場合、 Edge属性len

ここにコード例、グラフを描画する方法Gと、ノード間の距離を広げてGraphvizファイルgvfileに保存する方法(fdpのデフォルトの距離は0.3):

A = nx.to_agraph(G)
A.Edge_attr.update(len=3)
A.write(gv_file_name)

2つのコメント:

  1. 通常、lenをグラフ内のノードの数で調整することをお勧めします。
  2. len属性は、fdpおよびneatoアルゴリズムによってのみ認識されますが、たとえばsfdpアルゴリズムによって。
3
halloleo