python=でnetworkxを使用して、隣接するマトリックスをグラフに変換しようとしました。私の「加重」グラフには約8000ノードと14000エッジがあります。優れたレイアウトフォームまたは他のパッケージ、ツールがありますか?グラフがより美しくなりますか?結果として、ノードのエッジの重みが高くなるほどノードが近くなるため、クラスターノードを分析できます。
Networkxドキュメントで提供されているすべてのレイアウトを試しました。私もgephiを使用しようとしましたが、それでも私の理想には少し満足できません。これは、networkxでの外観です。すべてのクラスターを表示できますが、集中恐怖症の人には少し恐ろしいように見えます。
以下は、グラフを描くために使用したコードです。
G = nx.Graph()
for i in range(10000):
for j in range(10000):
if mat[i][j] > 10:
G.add_Edge(a[i], a[j], weight=mat[i][j])
pos = nx.nx_pydot.graphviz_layout(G)
plt.figure(figsize=(8, 8))
plt.axis('off')
nx.draw_networkx(G, pos=pos, with_labels=False, node_size=25, edgecolors='black', Edge_color='b')
plt.show()
あなたの質問のコンテキストでは、グラフを視覚化する3つの方法があります。
これらの方法を1つずつ確認します。
グラフには8000ノードと14000エッジがあります。エッジのないノードのみを描画する必要があると想像してみましょう。したがって、平均的なFullHDディスプレイの場合、次のようになります。
ノードあたり_1920 * 1080 / 8000 = 259
_ピクセル。それは:
sqrt(259) = 17
17×17ピクセル。表示全体をノードでタイル表示する場合はノード。ノードラベルを描画する場合は、次のものが必要です。
17 - 1 * 2 (outer node borders) - 1 * 2 (inner node borders) = 13×13
square。最小の可能なフォント(私は話さない 難解 フォント)は3×3(+1)
サイズを持っているので、ノードごとに最大9文字を格納できます。
次のようになります。
そして、まだグラフのエッジを描画していません!それをしたい場合は、以下を使用します。
グラフ要素ごとの1920 * 1080 / (8000 + 14000) = 94
ピクセル、および:
sqrt(94) = 9.7
-_9×9
_ px。ノードなので、単純なラベルを付けることはほぼ不可能です。
1つの画面のグラフ全体が常に恐ろしい混乱のように見えることは今や明らかです。したがって、この方法でグラフを描くことはできません。
1つの画面にグラフを描画できない場合は、頭をすくい上げて、いくつかの画面に描画するための方法を考案できます。それには2つの方法があります。
Matplotlibの場合、(figsize引数を使用して)非常に大きな図を作成し、グラフを(plt.savefigを使用して)画像にインポートします。
_import networkx as nx
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(40, 40))
G = nx.fast_gnp_random_graph(300, 0.02, seed=1337)
nx.draw(G, node_size=30)
plt.axis('equal')
plt.show()
fig.savefig('waka.svg')
_
そのため、大きなベクター画像を作成します(ここにその一部を示します)。
この場合、networkxで使用可能な任意のグラフレイアウトを使用できます。
別の方法は、グラフを描画するGraphviz外部ライブラリを使用することです。正直なところ、この場合、networkxはグラフを_.dot
_ファイルに変換し、それをGraphvizに送信します。主な欠点は、Graphvizがグラフを描画する方法を制御できないことです。しかし、それはかなり良いレイアウトなので、結果は許容できるでしょう。
次のPythonコードを使用して_.dot
_ファイルを生成します:
_import networkx as nx
G = nx.fast_gnp_random_graph(300, 0.02, seed=1337)
nx.nx_agraph.write_dot(G, './waka.dot')
_
次に、Graphvizを使用します。
_dot -Tsvg waka.dot >waka.svg
_
または無向グラフの場合:
_neato -Tsvg waka.dot -Goverlap=false >waka.svg
_
したがって、結果の画像は次のようになります(全体の一部です):
Graphvizにはさまざまなオプションが数多く用意されているため、グラフをほぼ希望どおりに変換できます。
グラフには、巨大な接続コンポーネント( [〜#〜] gcc [〜#〜] )のようなものがあり、多くの小さなサブグラフがあります。全体像は約580×580サイズで、GCCは約290×290サイズなので、GCCは以下を使用します。
キャンバスの_(290 × 290) ÷ (580 × 580) × 100 = 25%
_。 GCCのみを保持する場合は、描画するスペースが4倍になります。この場合、別の接続されたコンポーネントを別の画像に描画できます。
次のようなコードでGCCのみを保持できます。
_import networkx as nx
G = nx.fast_gnp_random_graph(300, 0.01, seed=1337)
gcc = max(nx.connected_components(G), key=lambda x: len(x))
H = G.subgraph(gcc)
nx.draw(G, node_size=30, node_color='red')
_
元のグラフを描画します:
そしてこの最後の行で:
nx.draw(H, node_size=30, node_color='red')
gCCのみを描画します。
グラフで他に何ができるか: