[Python]pyvisで作成できるノードの形を変更したり、画像に差し替えたりしてみた

pyvis で表示されるノードの形を色々なものに変更してみたよ。
2023.11.07

はじめに

pyvis で出力されるノードの形は、こんな感じの丸がデフォルトです。

これをもっとわかりやすいものに変更したいと思ったので、ノードの形を変更するためのオプションでどこまでできるのか確認してみました。

同じようにノードの形を変更したいと思った方や、pyvis でどこまで変更できるか知りたい方はぜひ試してみてください。

そもそもpyvisについて知りたい方はこちらのブログを参照してください。

やってみる

ノードの形を変更する時はshapeオプションを使用します。詳細はドキュメントを参照してください。

変更できる図形はたくさんあるのですが、分類すると主に 3 つあります。

  • ノードにテキストが表示されるもの
  • ノードにテキストが表示されるもの
  • ノードの図形を差し替えるもの
    • ローカル
    • icon

ノードの図形を差し替えるものは3種類オプションがあるのですが、ローカルの画像を参照する方法と、icon という特殊な方法があるので別で記載しています。

ノード内にテキストが表示されるもの

図形を変更した時、ノードの中にラベルが表示されるものは5種類です。

コードは以下の通り。

from pyvis.network import Network

net = Network()

net.add_node("A", shape="ellipse")  # 楕円
net.add_node("B", shape="circle")  # 円
net.add_node("C", shape="database")  # データベース
net.add_node("D", shape="box")  # 箱
net.add_node("E", shape="text")  # テキスト
net.show("pyvis.html", notebook=False)

大体想像通りの形で出力されました。長い文字列を入れるとノードも合わせて大きくなります。

ノード外にテキストが表示されるもの

次はテキストがノード外に表示されるものを試してみます。こちらは6種類ですね。

from pyvis.network import Network

net = Network()

net.add_node("A", shape="diamond")  # ひし形
net.add_node("B", shape="dot")  # 点
net.add_node("C", shape="star")  # 星
net.add_node("D", shape="triangle")  # 三角形
net.add_node("E", shape="triangleDown")  # 逆三角形
net.add_node("F", shape="square")  # 正方形
net.show("pyvis.html", notebook=False)

こちらも大体イメージできる形に変更できました。pyvis では shape オプションのデフォルトはshape="dot"が適用されているようですね。

ノードの図形そのものを差し替えるもの(ローカル)

最後にノードの図形を別のものに差し替えるパターンです。これは3種類あります。

ノードをローカルの画像と差し替えるのが2種類(image,circularImage)、CSS からアイコンを取得して差し替える(icon)のが1種類あります。少し icon は複雑なので後述するとして、まずはローカルの画像と差し替えるパターンからいきます。

A が単純な画像差し替え、B が画像を円形に切り抜いたものです。用意した画像に透過処理がされていたので、背景に青色が入っています。 コードは以下の通りです。

from pyvis.network import Network

net = Network()

net.add_node(
    "A",
    shape="image",
    image="./img/boy_01.png",
)
net.add_node("B", shape="circularImage", image="./img/boy_01.png")

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

ここで注意が必要なのは、画像のパスを指定するimage=の書き方です。今回以下のようなフォルダ構成で実行していました。

.
├── img
│   └── boy_01.png
├── pyvis.html
└── src
    └── pyvis_node-change.py

今回実行した py ファイルがsrc/pyvis_node-change.pyです。最初に相対パスでboy_01.pngを参照させようとした時は../img/boy_01.pngと指定したのですが、うまく表示されませんでした。

ここではpyvis.htmlがフォルダ直下に出力されているため、html から見て画像ファイルのパスを確認する必要がある点に注意しましょう。。今回 html が出力されている場所から見ると、画像ファイルの場所は./img/boy_01.pngとなります。

ノードの図形そのものを差し替えるもの(icon)

最後に icon のオプションです。最初どう使うのかいまいち分からなかったんですが、こちらのIssueを見つけてようやくアイコンの差し替えが出来ました。

出力される画像は以下のようにノードがアイコンに変わります。

実装したコードですが、上述した Issue を元に少し書き換えています。

from pyvis.network import Network

net = Network()

# groupsの定義
net.options.groups = {
    "users": {
        "shape": "icon",
        "icon": {
            "face": "FontAwesome",
            "code": "\uf0c0",
            "size": 50,
            "color": "orange",
        },
    },
    "table": {
        "shape": "icon",
        "icon": {"face": "FontAwesome", "code": "\uf0ce", "size": 50, "color": "green"},
    },
}

net.add_node("A", shape="icon", group="users")
net.add_node("B", shape="icon", group="table")
net.show("net.html", notebook=False)

# 出力されたhtmlの読み込み
with open("net.html", "r") as file:
    html_str = file.read()

# headタグ内にfont-awesomeのcssを追加
html_str = html_str.replace(
    "<head>",
    '<head><<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet"/>',
)
# htmlファイルの上書き
with open("net.html", "w") as file:
    file.write(html_str)

まず最初にノードへ定義する group でどのアイコンを使用するのかをnet.options.groupsで定義します。このままではアイコンが存在していないため、適切なアイコンは出力されません。

そこで、出力された html に対し、利用するアイコンの CSS を追加します。

html_str = html_str.replace(
    "<head>",
    '<head><<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet"/>',
)

ここで使用している URL は Font Awesome というアイコン集を利用しています。これを CSS として記載することで groups へ定義したcodeに対応するアイコンを設定しています。

CDN 上に配置されているアイコンを読み込むため、html を開いてから表示されるまで若干ラグがあったので注意してください。

できればローカルにダウンロードして参照させる方がいいかなと個人的には考えてます。

まとめ

一通り shape のオプションでできるノードの変更を試してみました。icon 以外は直感的に設定できるので使い方に困ることはなさそうですね。

ノードの形や画像変更したいと思った時の参考になれば幸いです。

参考