[Python]pyvisでネットワークグラフをインタラクティブなhtmlに出力してみた

pyvis を使うとネットワークグラフの html 出力があっという間にできちゃいます。
2023.11.02

はじめに

先日 NetworkX のライブラリを使ってネットワークグラフを作成してみたブログを書きました。

第一歩として node や edge の概念を学ぶことができたのですが、作成したグラフを html で出力してより見栄えを良くしたい要件がありました。

別のライブラリを探したところ、pyvis というライブラリを使うことで実現できるらしいので試していきます。

pyvisとは

pyvis はグラフの可視化用の Python ライブラリで、VisJSという JavaScript ライブラリのラッパーのようです。

このライブラリを使うことで、ネットワークグラフを作成した後 html ファイルとして出力できます。この出力された html には JavaScript が含まれており、インタラクティブな操作が可能です。

こんな感じで動かせます。ちょっと楽しい。

やってみる

pyvis にはチュートリアルが用意されていたので、このページに沿って試していきます。

環境構築

以下の環境で実施していきます。

❯ python --version                      
Python 3.10.9

事前準備として pyvis をインストールしていきます。

pip install pyvis

今回インストールされたバージョンは0.3.2です。

ノードの追加

任意のpyファイルを作成してチュートリアルに沿ってコードを書いていきます。

まずはノードを追加します。

from pyvis.network import Network

net = Network()

net.add_node(1, label="Node 1")
net.add_node(2)

net.show("pyvis.html", notebook=False)

実行すると、同じフォルダ直下にpyvis.htmlが出力されるので確認します。

シンプルなノード 2 つが作成されており、ラベルをつけた方にはNode 1と表示されていますね。

書き方を変更してリストで追加してみます。

from pyvis.network import Network

net = Network()

nodes = ["a", "b", "c", "d"]
net.add_nodes(nodes) # node ids and labels = ["a", "b", "c", "d"]
net.add_nodes("hello") # node ids and labels = ["h", "e", "l", "o"]
net.show("pyvis.html", notebook=False)

リスト形式で追加したノード、helloの文字列で追加したノードがまとめて表示されました。add_nodesの関数で追加すると文字列が 1 文字ずつの扱いになるのがわかります。

ノードのプロパティ

ノードに対しては様々なプロパティを設定できます。設定できるプロパティの詳細は VisJS に依存しているようなので、こちらのドキュメントから確認する必要があります。

ノードにまとめてプロパティを追加したコードがこちら。

from pyvis.network import Network

net = Network()

net.add_nodes(
    [1, 2, 3],
    value=[10, 100, 400],
    title=["I am node 1", "node 2 here", "and im node 3"],
    x=[21.4, 54.2, 11.2],
    y=[100.2, 23.54, 32.1],
    label=["NODE 1", "NODE 2", "NODE 3"],
    color=["#00ff1e", "#162347", "#dd4b39"],
)
net.show("pyvis.html", notebook=False)

座標やら色、タイトル等々を付与したノードが作成されました。タイトルはホバーすると表示されます。

エッジの追加

ノード同士を紐づけるためのエッジを追加します。

from pyvis.network import Network

net = Network()

net.add_node(0, label='a')
net.add_node(1, label='b')
net.add_edge(0, 1)

net.show("pyvis.html", notebook=False)

2 つのノードを結ぶエッジが追加されました。

エッジのプロパティ

エッジもノードと同様にプロパティを追加できます。こちらもVisJSのドキュメントを参照しましょう。

エッジの色やラベル、線の太さを変更してみました。

from pyvis.network import Network

net = Network()

net.add_node(0, label="a", id=0)
net.add_node(1, label="b")
net.add_edge(0, 1, label="ab", font={"align": "top"}, color="red", width=3)

net.show("pyvis.html", notebook=False)

たくさんあるプロパティの中の一部なので、他にも色々触ってみても面白そうです。

NetworkXのグラフをpyvisで変換

冒頭で紹介した NetworkX という可視化ライブラリですが、このライブラリで作成したグラフを pyvis で読み込んで出力もできます。

前回のブログではこのようなグラフを NetworkX で作成しました。

これを pyvis で出力してみます。

from pyvis.network import Network
import networkx as nx

net = Network()
G = nx.Graph()

G.add_nodes_from(["A", "B", "C", "D"])
G.add_edges_from([("A", "B"), ("B", "C"), ("C", "D"), ("A", "C"), ("B", "D")])

sizes = [1200, 1800, 2400, 3000]
nx.draw(G, node_color="red", node_size=sizes, with_labels=True)

net.from_nx(G)
net.show("pyvis.html", notebook=False)

nx.drawまでは NetworkX でグラフを作成し、それをnet.from_nxで取り込んでいます。

出力された html がこちら。

ノードやエッジ数は保持されていますが、NetworkX で設定したノードの色やサイズなどは保持されないようです。ノードのサイズも pyvis デフォルトより小さくなっているので、NetworkX 経由で利用する際は注意したいですね。

まとめ

pyvis の使い方をチュートリアルを通して試してみました。短いコード量でここまでインタラクティブな html が出力できることに驚いてます。 ノードやエッジのプロパティも豊富ですし、グラフの可視化には便利なライブラリだと感じました。

出力した html を触って遊ぶのも楽しいので、是非試してみてください。

参考