draw関数だけじゃない NetworkXで綺麗なグラフを描く方法

NetworkXにはdraw関数以外にもグラフを描画する方法が用意されているのをご存じだろうか?

実は13個の関数が用意されている。

どの関数を使えば美しいグラフを描けるのか比較検証していく。

networkxには13の描画関数がある

一口にグラフ描写といっても

*draw_networkx

*draw_networkx

*draw_circular

*draw_kamada_kawai

*draw_random

*draw_spectral

*draw_spring

*draw_shell

これだけの手段がある。 関数によって描画されるグラフも大きく異なる。

違いを見てみよう。

描写の比較

f:id:hirataku322:20200529083104p:plain

全く同じグラフを異なる関数で描画したところ、

左の4つが汚く、右の4つが綺麗になった。

特に左下はとても見にくい。 グラフの構造をランダムに決定しているからだ。

一方右上はとても美しい。 アルゴリズムに基づきグラフ構造を決定しているからだ

このように描画する関数によって全く異なる結果が得られる。 困ったらnetworkx.drawing.layout.kamada_kawai_layoutでグラフを描画する、と覚えておこう。

上記画像のソースコード

import networkx as nx
import matplotlib.pyplot as plt

def draw(G, func, ax):
    func(G, ax=ax)
    ax.set_title(str(func).split(" ")[1])

#入力グラフ作成
G = nx.Graph()
G.add_edges_from([(i, j) for i in range(4) for j in range(4, 8) if i != j])

#プロット
fig, axs = plt.subplots(2, 4, figsize=(2 * 4, 2 * 2))
draw(G, nx.draw,              axs[0,0])
draw(G, nx.draw_networkx,     axs[0,1])
draw(G, nx.draw_circular,     axs[0,2])
draw(G, nx.draw_kamada_kawai, axs[0,3])
draw(G, nx.draw_random,       axs[1,0])
draw(G, nx.draw_spectral,     axs[1,1])
draw(G, nx.draw_spring,       axs[1,2])
draw(G, nx.draw_shell,        axs[1,3])
plt.tight_layout() #各グラフ間の余白を自動調整
plt.show()

各関数の詳細

関数の簡単な説明と、リファレンスの紹介を行う。

draw

恐らく一番使われている関数。無難なグラフを描ける。

しかしランダム性があり、プロットする度に形が変わる。

f:id:hirataku322:20200529085220p:plain

あまりおすすめはしない。

draw — NetworkX 1.10 documentation

draw_networkx

matplotlibを使って描画する関数。 ノードラベルや軸を表示させたいときにはこれを使う。

draw_networkx — NetworkX 1.10 documentation

networkx.draw_circular

ノードが円周上に並ぶよう描画する関数。 ノード数が少ないときは綺麗に描けると思う。

draw_circular — NetworkX 1.10 documentation

kamada_kawai_layout

僕のおすすめ。 力学モデルを組み入れたグラフ構造アルゴリズムに基づいて描画する関数。

networkx.drawing.layout.kamada_kawai_layout — NetworkX 2.4 documentation

draw_random

ランダムに描画する関数。 当然ぐちゃぐちゃになる。何のために存在するのかイマイチ理解してない。

networkx.drawing.nx_pylab.draw_random — NetworkX 2.4 documentation

draw_spectral

あるグラフ構造アルゴリズムを用い描画する関数。 このアルゴリズムで描画されるグラフ構造をスペクタルレイアウトというらしい。

networkx.drawing.nx_pylab.draw_spectral — NetworkX 2.4 documentation

draw_spring

ノード間の相対的な位置関係を考慮したグラフ構造アルゴリズムで描画する関数。

networkx.drawing.nx_pylab.draw_spring — NetworkX 2.4 documentation

draw_shell

グラフ構造アルゴリズムで描写する関数。 貝っぽく配置される?二部グラフは貝に比較的似ていると思う。二部グラフっぽく配置される?

networkx.drawing.nx_pylab.draw_shell — NetworkX 2.4 documentation

まとめ

f:id:hirataku322:20200529083104p:plain

迷ったら

networkx.drawing.layout.kamada_kawai_layout

を使おう!