はじめに
Gradio は、機械学習モデルのデモを簡単に作成できる便利なライブラリです。しかし、単にモデルの入出力を表示するだけでなく、ネットワーク図のような複雑なデータをインタラクティブに可視化したい場合があります。Pyvis は、インタラクティブなネットワークグラフを作成するための優れたツールです。この記事では、Pyvis で生成したグラフを Gradio アプリケーションに埋め込む方法をご紹介します。
目的
Pyvis で作成したインタラクティブなネットワーク図を Gradio アプリケーション内で表示します。
方法
Gradio は直接 Pyvis の HTML 出力をレンダリングすることができません。そこで、以下の手順で実現します。
- Pyvis を使ってネットワーク図を HTML ファイルとして生成します。
- 生成した HTML ファイルを一時ディレクトリに保存します。
-
demo.launch()のallowed_paths引数にそのディレクトリを指定し、Gradio がアクセスできるようにします。 -
gr.HTMLコンポーネント内でiframeを使用して、HTML ファイルを埋め込みます。iframeのsrc属性は Gradio の内部 API パス/gradio_api/file=<path_to_html>を指すように設定します。
アーキテクチャ図
ざっくりと登場人物をご紹介します。Gradio は UI を配信する FrontEnd、内部処理をする Backend、ファイルを送信する FileServer に分けています。
シーケンス図
登場人物間のメッセージのやり取りを時系列で示します。ユーザーは省略しました。
結果
Gradio アプリケーション内に Pyvis のインタラクティブなネットワーク図を表示できました。マウスでノードをドラッグしたり、ズームしたりできます。(下の図は画像なので操作できません)
コード
import os
import tempfile
import gradio as gr
import networkx as nx
from pyvis.network import Network
# Gradioからアクセス可能な一時ディレクトリを作成
HTML_OUTPUT_DIR = tempfile.mkdtemp()
def create_network_visualization():
"""
NetworkXでグラフを作成し、PyvisでHTMLに変換して、
Gradioで表示するためのiframe文字列を返します。
"""
# NetworkXでサンプルグラフを作成 (クラックハートのカイトグラフ)
g = nx.krackhardt_kite_graph()
# Pyvis Networkオブジェクトの初期化
net = Network(
height="500px",
width="100%",
bgcolor="#222222",
font_color="white",
cdn_resources="remote",
)
# NetworkXグラフをPyvisネットワークに変換
net.from_nx(g)
# HTMLファイルとして一時ディレクトリ��保存
file_path = os.path.join(HTML_OUTPUT_DIR, "network.html")
net.write_html(file_path)
# Gradioで表示するためのiframeを返す
# /gradio_api/file=... はGradioがallowed_paths内のファイルにアクセスするためのパス
return f'<iframe src="/gradio_api/file={file_path}" width="100%" height="500px"></iframe>'
# GradioアプリケーションのUIを定義
with gr.Blocks() as demo:
gr.Markdown("# GradioとPyvisによるネットワーク可視化のサンプル")
html_output = gr.HTML()
# ページ読み込み時にグラフ生成関数を実行
demo.load(fn=create_network_visualization, inputs=None, outputs=html_output)
if __name__ == "__main__":
# Gradioアプリケーションを起動
demo.launch(
server_name="0.0.0.0",
server_port=7860,
# HTMLファイルが保存されているディレクトリへのアクセスを許可
allowed_paths=[HTML_OUTPUT_DIR],
)
実行方法
pip install gradio pyvis networks
python sample.py
解説
コードの重要なポイントと、うまく動作させるための注意点をいくつか解説します。
-
tempfile.mkdtemp(): Pyvis が生成する HTML を保存するための一時的なディレクトリを作成します。Gradio がこのディレクトリ内のファイルにアクセスできるようにします。 -
net.write_html(file_path): 作成したネットワーク図を HTML ファイルとして保存します。 -
f'<iframe src="/gradio_api/file={file_path}" ...>': これが核心部分です。Gradio のHTMLコンポーネントは HTML 文字列を受け取ります。ここにiframeを埋め込むことで、外部の HTML ファイルを表示できます。srcに指定された/gradio_api/file=という特別なパスは、launchメソッドのallowed_pathsで許可されたディレクトリ内のファイルにアクセスするための Gradio の仕組みです。-
srcdocではなくsrcを使う:iframeにはsrcdoc属性もあり、HTMLコンテンツを直接埋め込めますが、Pyvisが生成するHTMLは内部でJavaScriptを使用しています。多くのブラウザではセキュリティ上の理由からsrcdoc内のJavaScriptの実行が制限されるため、インタラクティブな機能が正しく動作しません。そのため、必ずsrc属性でファイルを指定する必要があります。
-
-
demo.launch(allowed_paths=[HTML_OUTPUT_DIR]): Gradio サーバーを起動する際に、allowed_pathsを設定することが不可欠です。これにより、指定されたディレクトリへのファイルアクセスが許可され、iframeが正しくコンテンツを読み込めるようになります。 -
pythonコマンドで実行する: このスクリプトはpython sample.pyのように直接実行する必要があります。gradio sample.pyコマンドで起動した場合、/gradio_api/file=のパスでファイルが正しく提供されず、iframe内にコンテンツが表示されません。これは、gradioコマンドがif __name__ == "__main__":ブロック内のdemo.launch()に渡したallowed_pathsの設定を認識しないためと考えられます。pythonコマンドで実行することで、意図通りに設定が適用されます。
まとめ
この手法を用いることで、Gradio アプリケーションに Pyvis によるリッチでインタラクティブな可視化を組み込むことができました。このサンプルは簡単なものですが、Gradio をグラフデータベースのフロントエンドとして利用することで、柔軟で複雑なグラフ操作をインタラクティブなグラフ表現と組み合わせることができます。JavaScript で vis.js に対して色々と操作することもできますが、Gradio を使うことで Python の様々なライブラリが利用できるのが魅力です。
振り返ってみると、やっていることはファイルを iframe で読み込ませるだけの話です。様々なコンテンツをファイル経由で送信できるので、HTML ファイルじゃなくても PDF でもいいですし、色々と応用範囲が広い方法です。Gradio は少ないコードでリッチな UI が作れるので非常に強力ですが、融通が効かない一面もあります。ある意味、抜け穴っぽい使い方ですが、知っていて損はない使い方だと思います。
最後までお読み頂きありがとうございました。
参考情報:使用ライブラリ
この記事で使用する 3 つの主要なライブラリについて簡単に紹介します。
Gradio
Gradio は、機械学習モデルのWebデモを迅速に構築するための Python ライブラリです。数行のコードで、画像、テキスト、音声などの入出力に対応したインタラクティブな UI を作成できます。
Gradio Guide Security and File Access にファイルの扱いについて書いています。(記事を書いた後に見つけたけど、先に読んでいればよかった・・・)
Pyvis
Pyvis は、インタラクティブなネットワークグラフを作成するための Python ライブラリです。内部的には JavaScript の vis.js ライブラリを利用しており、動的なネットワーク可視化を簡単に実現できます。ノードのドラッグ、ズーム、カスタマイズが可能です。
NetworkX
NetworkX は、複雑なネットワーク(グラフ)の作成、操作、研究を行うためのPythonライブラリです。ノード、エッジ、およびそれらの属性を扱うための豊富なデータ構造とアルゴリズムを提供します。Pyvisと組み合わせることで、グラフデータを効率的に生成・操作し、可視化することができます。
参考情報:この記事の制作について
この記事は、Gemini CLI & Gemini API(課金) を使って制作しました。もともとはグラフデータの分析をしていたのですが、どうしても Gradio で Pyvis したい気持ちになってしまい、試行錯誤しているうちにサンプルコードを作ってしまったので記事にしています。サンプルコードの生成にも Gemini CLI を使っています。
まず、サンプルコードの生成には非常に多くの試行錯誤が必要でした。Streamlit で表示するのは秒殺だったのですが、Gemini CLI に何度リクエストを出してもまともなに動作するコードが生成できないので、デバッグ用のコードを生成させて追い込んでいった感じです。最終的には gr.File() でダウンロードさせる機構をチェックしてから安定動作する流れを掴みました。
(ちなみに Streamlit はシンプルで使いやすいですがサーバー側で内部状態が欲しいシチュエーションは辛いなと思います。UI 操作のたびにリロードされると・・・)
コードも記事も「手で作ったほうが早いのでは」と思う程度の時間は掛かっていますし、1000円程度の API コストが掛かっています。間尺に合わない感じはしますが、Gemini CLI を使ったワークフローを知ることができたので良しとしたいと思います。
