graph-tool チートシート（可視化編）

# はじめに

グラフの可視化のツールは様々なものがあるが、[graph-tool](https://graph-tool.skewed.de/)はその中でも最も強力といっても過言ではないだろう。
いろいろな可視化の方法が実装されているだけでなく、OpenMP化したC++で実装されているのでかなり大きなネットワークでも描画することができる。
例えばこのような可視化ができる。( https://graph-tool.skewed.de/ より )

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/6373a651-a795-9d0e-2ed5-e9508ee1f3cb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/b343013d-4dd9-b4ee-e134-667fd7bca8ce.png)

ここではgraph-toolを用いた可視化について典型的な処理をまとめていく。

## reference

https://graph-tool.skewed.de/static/doc/draw.html

# 動作環境

動作確認環境は以下の通り

- python 3.9.0
- graph-tool 2.35
- numpy, matplotlib

以後のサンプルコードでは、前提条件として以下のモジュールをimportしている。

```py3
import graph_tool.all as gt
import numpy as np
import matplotlib.pyplot as plt
```

またサンプルデータとして以下のものを用いる。（ある小説における名詞と形容詞の隣接関係から構築したネットワーク）

```py3
g = gt.collection.data['adjnoun']
```

# Jupyter notebookで実行するかターミナルから実行するか

graph-toolで可視化するコードを実行する場合、jupyter notebookで実行するかターミナルで実行するかに依存して若干挙動が異なる。
可視化するスクリプトをjupyterから実行した場合、ノートブック内にインラインで表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/d3b75e51-e7ce-d595-2dea-c7de17215aca.png)

一方でスクリプトをターミナルから実行した場合、interactiveなGUI windowに描画される。ノードをマウスでドラッグ＆ドロップして動かしたり、選択したノードとそのエッジをハイライトしたりできる。用途に応じて使い分けたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/b08ffed6-d0ed-0557-1a63-3b6b33c66ded.png)


# コード

## とりあえず描画する

`gt.graph_draw`メソッドを呼べば良い

```py3
gt.graph_draw( g )
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/8c7b0954-4c3d-1431-9b86-7547d40052e0.png)

## ファイル出力する

`output`オプションにファイル名を指定する。拡張子に応じてフォーマットを決めてくれる。
pdf, svg, png, jpgなど様々な形式に対応している。

```py3
gt.graph_draw(g, output = 'graph.pdf')
```

pngなどのラスタ形式の画像で画像の大きさを変えたい場合は、`output_size` オプションを指定する

```py3
gt.graph_draw(g, output = 'graph.png', output_size=(1000,1000))
```

## ノードにラベルを表示する

VertexPropertyで指定する文字列を表示するには`vertex_text`オプションを指定する。

```py3
gt.graph_draw(g, vertex_text = g.vp.label)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/f24d2851-76eb-42b7-a8e5-ac1b5b793d9c.png)


ノードの外側に表示したいときは`vertex_text_position = 0`を指定する。

```py3
gt.graph_draw(g, vertex_text = g.vp.label, vertex_text_position = 0)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/7b8bae4f-b355-5495-de03-ed1674fc85eb.png)


その他、オプションをいじることでテキストの色やフォントなど細かく調整できる。

```py3
gt.graph_draw(g, vertex_text = g.vp.label, vertex_text_position = 0, vertex_font_size = 16, vertex_text_offset = [-1,1], vertex_text_color=(255,0,255,255))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/1d309336-0d14-193a-6785-cdeb0f9a386d.png)

## レイアウトを変更する

graph-toolには様々なlayoutアルゴリズムが用意されている。まずレイアウトを計算し、得られた位置情報を`graph_draw`の引数に渡す。

```py3
pos = gt.radial_tree_layout(g, 0)
gt.graph_draw(g, pos = pos)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/f015aa0d-fa25-8c26-6155-da643243d1b4.png)

## ノードやエッジの見た目を次数などの統計量に応じて変更する

ノードやエッジのサイズや色を次数や他のネットワーク統計量に応じて変更することができる。
例えば、次数に応じてノードの大きさを変更するには以下のようにする。

```py3
deg = g.degree_property_map("total")
gt.graph_draw(g, vertex_size = deg)
```

スケールをうまく調整するには `gt.prop_to_size` メソッドを使うと良い。指定した最小値、最大値になるように適切にスケーリングしてくれる。logスケールにすることもできる。

```py3
gt.graph_draw(g, vertex_size = gt.prop_to_size(deg,mi=5,ma=20,log=False) )
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/2ed119c7-4cca-b08a-7772-061005dc1aff.png)

工夫すれば他にも幅や色味など色々と変更できる。

```py3
deg = g.degree_property_map("total")
ebet = gt.betweenness(g)[1]   # edge betweeness
gt.graph_draw(g,
              vertex_size=gt.prop_to_size(deg,mi=5,ma=20,log=False),
              vertex_fill_color=gt.prop_to_size(deg,log=False),
              vcmap=(matplotlib.cm.inferno, .9),
              vorder=deg,
              edge_color=gt.prop_to_size(ebet),
              eorder=ebet,
              edge_pen_width=gt.prop_to_size(ebet,mi=1,ma=5,log=False),
              ecmap=(matplotlib.cm.bone, .7)
             )
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/f4f73e62-9090-f88d-4257-430159cac85e.png)