🌊

[Package] GraphPlot.jl (v0.4.4) の plot パラメータ全部見る

2021/04/28に公開

GraphPlot.jlというよく使っているパッケージがあるのですが,ドキュメントが整備されていません.特にグラフのPlotを行うメインの関数である gplot() のパラメータを一覧にしてメモします (毎回ソースを見に行くのが面倒なので…).

環境

  • Julia 1.6.0
  • LightGraphs.jl v1.3.5
  • GraphPlot.jl v0.4.4
  • Compose.jl v0.9.2
  • Colors v0.12.7

準備

パラメータを調べるために準備をします.

グラフデータの準備

直接プロットとは関係ないのですが,LightGraphs.jl に様々なグラフデータの生成法が実装されているいます.

本稿では Erdős–Rényi model で適当なサイズのグラフ Gを作成しました.

レイアウト

レイアウト (layout) は,グラフ G=(V, E) の頂点 v をどの (x_v, y_v) に位置させるかを計算するために用意されています.グラフ可視化などの分野で研究・開発されるものや,直接全てのノードの座標をベクトルとして渡すか,レイアウトを計算する関数にグラフ G を渡して計算してもらいます.GraphPlot.jlには以下が実装されています.

  • random layout
  • spring layout
  • circular layout
  • shell layout
  • spectral layout

適当な関数を呼んでください.本記事では次のようにspring layoutを利用しています.実はspring layoutはデフォルトの関数なので,明示的に与えなくても同じ結果になります.

using LightGraphs
using GraphPlot
using Compose
using Cairo # 保存用
using Colors # 色用

set_default_graphic_size(7cm, 7cm)
g = erdos_renyi(10, 15)
gplot(g, layout=spring_layout)

出力です.

描画全パラメータ

GraphPlot.jl の実装では N=|V|, \mathrm{NE}=|E| です.これらの多くのパラメータは,値で与える場合には全てのノード/エッジに対して影響を与え,逆にノード数やエッジ数と同じ長さのベクトルとして与える場合には個別の設定値として影響を与えます.

パラメータ デフォルト値 意味
NODESIZE \frac{3.0}{\sqrt{N}} ノードの最大描画サイズ
nodesize 1.0 各ノードの描画サイズ
nodelabel nothing 各ノードに描画されるラベル (ノード数だけ必要)
nodelabelc colorant"black" 各ノードラベルの色
nodelabeldist 0.0 各ノードラベルがノード中心から描画される距離
nodelabelangleoffset \frac{\pi}{4.0} 各ノードラベルの描画角度
NODELABELSIZE 4.0 ノードラベルの最大描画サイズ
nodelabelsize 1.0 ノードラベルの描画サイズ
nodefillc colorant"turquoise" ノードの描画色
nodestrokec nothing ノード縁の描画色
nodestrokelw 0.0 ノード縁の太さ
edgelabel [] 各エッジに描画されるラベル (エッジ数だけ必要)
edgelabelc colorant"black" エッジラベルの描画色
edgelabeldistx, edgelabeldisty 0.0 各エッジラベルがエッジ中心から描画される距離
EDGELABELSIZE 4.0 エッジラベルの最大描画サイズ
edgelabelsize 1.0 エッジラベルの描画サイズ
EDGELINEWIDTH \frac{0.25}{N} エッジの最大描画太さ
edgelinewidth 1.0 エッジの描画太さ
edgestrokec colorant"lightgray" エッジの描画色
arrowlengthfrac 0.1 エッジ長さのうち有向エッジの矢印頭部分の比率
arrowangleoffset \frac{\pi}{9} 矢印描画の広さ角度
linetype straight エッジの描画を直線・曲線 (curve) にします
outangle \frac{\pi}{5} エッジが曲線のときの出る角度を変更します

描画作例

ノードやエッジの大きさについて

全部大文字のパラメータと小文字のパラメータが入り乱れています.具体的な実装はこのような形で,ノードやエッジの情報が拡大縮小されています.これは Compose.jl を利用することが原因だと思います.適当にいじってください.むちゃくちゃ調整面倒なんで,適当にイジってください.

max_nodesize = NODESIZE / maximum(nodesize)
nodesize *= max_nodesize
max_edgelinewidth = EDGELINEWIDTH / maximum(edgelinewidth)
edgelinewidth *= max_edgelinewidth
max_edgelabelsize = EDGELABELSIZE / maximum(edgelabelsize)
edgelabelsize *= max_edgelabelsize
max_nodelabelsize = NODELABELSIZE / maximum(nodelabelsize)
nodelabelsize *= max_nodelabelsize
デフォルト NODESIZE=0.5 NODESIZE=0.25 NODESIZE=0.01

ノード/エッジラベル

ノードとエッジの個数分だけ与えてあげましょう.

# ノードのみ
sg = spring_layout(g)
fixed_layout = g -> sg # 毎回位置が変わらないように固定します
gplot(g, nodelabel=1:nv(g), layout=fixed_layout)

# ノード,エッジ
gplot(g, nodelabel=1:nv(g), edgelabel=1:ne(g), layout=fixed_layout)

出力は次のようになります.

デフォルト nodelabel nodelabel + edgelabel

ノード/エッジの色・位置情報

ノードラベルが頂点に重なっているとウザいときがあるので,ずらすには dist です.表示位置を回転させるのは angleoffset です.ついでに特別に 20 のノードだけ色を変えたり,縁をいじったりするのもやってみましょう.エッジをいじる場合もだいたい同じです.

# デフォルト
gp = gplot(g, nodelabel=1:nv(g), layout=fixed_layout)

# 距離を離す
gp = gplot(g, nodelabel=1:nv(g), nodelabeldist=3,
              layout=fixed_layout)

# 回転させる (π)
gp = gplot(g, nodelabel=1:nv(g), nodelabeldist=3,
              nodelabelangleoffset=π, layout=fixed_layout)

# 20のノードだけ色を変える
nc = [(i == 20) ? colorant"tomato" : colorant"white" for i in 1:nv(g)]
gp = gplot(g, nodelabel=1:nv(g), nodelabeldist=3,
              nodelabelangleoffset=π, nodefillc=nc,
              layout=fixed_layout)

# 20のノードの縁を青色にする
nslw = [(i == 20) ? 2.0 : 0.0 for i in 1:nv(g)]
gp = gplot(g, nodelabel=1:nv(g), nodelabeldist=3,
              nodelabelangleoffset=π, nodestrokelw=nslw,
              nodestrokec=colorant"blue", layout=fixed_layout)
デフォルト 距離を離す 回転させる 色を変える ノードの縁を塗る

エッジを直線・曲線切り替える

実装のコメントなどで説明されていませんが,実装上は用意されています.

# デフォルト
gp = gplot(g, nodelabel=1:nv(g), layout=fixed_layout)

# 曲線エッジ
gp = gplot(g, nodelabel=1:nv(g), layout=fixed_layout, linetype="curve")

# 曲線エッジ (抑え気味)
gp = gplot(g, nodelabel=1:nv(g), layout=fixed_layout, linetype="curve", outangle=π/18)
デフォルト 曲線エッジ 曲線エッジ (抑え気味)

有向グラフの例

作ってみましょう.nodestokelw はなぜか実装上は EDGELINEWIDTH に律速されるので気をつけましょう.

# ただのグラフ ([1, 2, 3]と[0, 0, 0]がx/y座標です)
gg = DiGraph(3)
add_edge!(gg, 1, 2)
add_edge!(gg, 2, 3)
p = gplot(gg, [1, 2, 3], [0, 0, 0], nodelabel=["A", "B", "C"], nodefillc=colorant"tomato",
    nodestrokelw=0.1, EDGELINEWIDTH=0.5, nodestrokec=colorant"black",
    edgestrokec=colorant"black")

# エッジの頭を調整したグラフ
p = gplot(gg, [1, 2, 3], [0, 0, 0], nodelabel=["A", "B", "C"], nodefillc=colorant"tomato",
    nodestrokelw=0.1, EDGELINEWIDTH=0.5, nodestrokec=colorant"black",
    edgestrokec=colorant"black", arrowlengthfrac=0.3)
p

結果を見てみます.エッジの種類 (塗られた矢印など) は今の所変えられなさそうです.

ただのグラフ 調整したグラフ

まとめ

以上使いそうなパラメータを (ほぼ) 全てまとめました.

https://github.com/JuliaGraphs/GraphPlot.jl

Discussion