LoginSignup
0
0

networkxの頂点を一様に配置する関数

Last updated at Posted at 2023-06-15

Pythonのネットワーク計算用パッケージnetworkxのグラフの頂点を一様に配置する関数を作りました。以下の図のように各頂点が互いに重ならないような配置が出てきます。

uniform_layout.png

比較用にバネモデルの場合を載せます。パラメータkで多少は調節出来ますが限界があります。
spring_layout.png

以下が最小限のソースコードです。

import numpy as np
import networkx as nx
from scipy.cluster.hierarchy import distance

def uniform_layout(G, alpha=0.1, n_iter=None, seed=None, **kwargs):
  pos = nx.spring_layout(G, seed=seed, **kwargs)
  X = np.array(list(pos.values()))
  if n_iter == None:
    n_iter = 10 * len(G)
  for _ in range(n_iter):
    D = distance.squareform(distance.pdist(X))
    np.fill_diagonal(D, None)
    X += alpha * (X - X[np.nanargmin(D, axis=0)])
    X = X.clip(-1,1)
  return dict(zip(pos.keys(), X))

Gistに説明付きバージョンも置きました。
https://gist.github.com/okumakito/3c0f8166a99e6b617dca2c5556a6ebfa

使い方は他のnetowrkxのレイアウト関数と同様です。

>>> pos = uniform_layout(G)
>>> nx.draw_networkx(G, pos=pos)

円形バージョン (2024/04/28追記)

描画領域を正方形でなく円形にしたバージョンも用意しました。上記の最小限のコードで

X = X.clip(-1,1)

の部分を以下に変えるだけです。

X = (X.T / np.linalg.norm(X,axis=1).clip(1,None)).T

Gist版の方はオプションで切り替えられるようにしました。

>>> pos = uniform_layout(G, circle=True)
>>> nx.draw_networkx(G, pos=pos)

見た目は以下のようになります。

tmp.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0