私は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)
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に個別にパーツを描画させる必要があります。
これは、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>
ボーナス-最短経路:
>>> nx.dijkstra_path(G, 'CDKN1A', 'MLH3')
['CDKN1A', 'CDK2', 'CHEK2', 'BRCA1', 'PTEN', 'MLH3']
グラフには大量のデータがあるため、混乱を取り除くのは難しいでしょう。
標準レイアウトを使用することをお勧めします。あなたは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
を使用して、ノード間のグローバル距離を増やすことができます。
ノード間の距離を調整する方法についての質問に答えるために、 フックの答え を展開します。
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つのコメント:
len
をグラフ内のノードの数で調整することをお勧めします。len
属性は、fdp
およびneato
アルゴリズムによってのみ認識されますが、たとえばsfdp
アルゴリズムによって。