Keiです。自分は大学院で複雑系科学という領域の研究をしているのですが、そこでよくネットワーク(人間関係や感染症の広がりなど)を綺麗に可視化したい、という場面があります。
これまでそういうシーンではPythonのNetworkXに頼っていたのですが、最近研究で使うシミュレーションコードを全てPythonからJuliaに移行したのもあってグラフ描画用のスクリプトもJuliaで書きたい! という衝動に駆られていました。
そこでざっと調べてみたところJuliaでネットワークを可視化するためのパッケージは既に山ほど開発されており、僕が分かる範囲だけでもこれだけありました。
通常のグラフ描画パッケージ(Gadfly, GR, PyPlot, Plotly, Plots, Makie, etc)に似て色々あるけど結局どれが良いのか分からないという状況です。
そこでひとまず判断軸として
- 継続的にメンテナンスされている
- ドキュメントが綺麗で充実している
- 記述が簡潔
- 静的な無向グラフが可視化できれば良い(有向グラフはめったに描かないし別にグラフをマウスでグリグリ出来なくていい)
の4つを設けた結果、GraphPlotを採用することにしました。まぁネットワーク分析系パッケージのコア部分であるLightgGraphsのチュートリアルでもGraphPlotが使われてるくらいなんで1番手堅い選択かなという気はします。
以下LightGraphsで作ったネットワークをGraphPlotで可視化して画像ファイルにするまでの流れを説明します。
前提
Julia v1.0.0
IJulia v1.18.1
必要なパッケージ
- GraphPlot (ネットワーク可視化用ライブラリ)
- LightGraphs (ネットワークの生成に必要)
- Compose (グラフの保存に必要)
- Cairo (グラフをpngかpdfで保存したい時だけ必要。svgなら不要)
- Fontconfig (同上)
パッケージのインストールと読み込み
まずはJuliaのREPLを立ち上げて]を押してpkgモードに入り、上で挙げたパッケージを全部入れます。
(v1.0) pkg> add GraphPlot
(v1.0) pkg> add LightGraph
(v1.0) pkg> add Compose
(v1.0) pkg> add Cairo
(v1.0) pkg> add Fontconfig
CairoとFontconfigを入れるときにエラーが大量に出るかもしれませんが動作には問題ないので無視してもらって大丈夫です。
次にpkgモードを抜けてJupyterを起動し, 必要なパッケージを読み込みます。
julia > using IJulia
julia > IJulia.notebook()
ここからはJupyter上で実行します。
using GraphPlot
using LightGraphs
using Compose
using Cairo
using Fontconfig
恐らくCairo, Fontconfig, Composeの読み込みでwarningを吐きますが無視して大丈夫です。
ここまでで準備が出来たので早速グラフを描いてみましょう。
サンプルとしてLightGraphsが提供しているbarabasi_albertグラフ(=BA-SFグラフ, スケールフリーネットワークの一種)を描画してみます。
# ノード数: 100, 平均次数: ~8 のBA-SFグラフを作る時の設定. 厳密にはこの設定だと平均次数は7.68になる。
g = LightGraphs.barabasi_albert(100, 4)
fig = GraphPlot.gplot(g)
出来た!!簡単!!
描画したグラフをpng形式で保存しておくには以下の一行でOK。
Compose.draw(PNG("barabasi_albert_graph.png", 10cm, 10cm), fig) # 引数で描画する際のグラフのサイズが指定できる
NetworkXと違って必要なパッケージがあちこちに散らばっているのが少し面倒ですが、一旦環境構築さえ出来てしまえばNetworkXと同じような感覚で使っていけそうです。
ノード・エッジにラベルを付けたり、ノードの大きさや色を変える方法も公式ドキュメントに綺麗にまとまっているので、見た目を細かく設定したい場合はそちらを参考にしてください。
次は外部データを読み込んでネットワークグラフを描く方法やマルチエージェントシミュレーションとの組み合わせ方について書こうと思います。
参考
http://juliagraphs.github.io/GraphPlot.jl/
https://github.com/JuliaGraphs/GraphPlot.jl