graph-toolのmacOSへのインストール方法

# はじめに

この記事ではネットワーク解析を行うライブラリ [graph-tool](https://graph-tool.skewed.de/) のインストール方法についてまとめる。このライブラリは[networkx](https://github.com/networkx) に似たライブラリで、pythonからグラフデータを操作したり、ネットワーク特徴量を計算したりする関数が実装されているライブラリである。

networkxはpure pythonで実装されているのに対して、graph-toolは内部はOpenMPを使ったC++で実装されているため計算が非常に速いという点が、networkxに対して優位な点である。
一方でpure pythonのライブラリのように単純に`pip install`するだけではインストールができず、新しいC++の仕様やGUIのライブラリも含む多くのライブラリに依存しているので手動でビルドすることが非常に難しい。

2020.10.1時点で最新のバージョン 2.35 ではパッケージ管理ツールでインストールできるようになり、インストールがだいぶ簡単になった。ここではmacOS上にインストールするための手順についてまとめる。

# 前提条件

- mac OS 10.15 Catalina
- python 3.8.5
- graph-tool 2.35

なお、私は普段は pyenv と pipenvを使ってpythonのバージョン管理とpackageの管理をしているので、できるだけこれらを利用する方法を紹介する。

# 様々なインストール方法

インストール方法はこちらのページにまとまっている。
https://git.skewed.de/count0/graph-tool/-/wikis/installation-instructions

ざっくりというと以下のような方法がある。

- dockerを使う方法
- anaconda を使う方法
- homebrew でシステムにインストールする方法
- 手動ビルド

これらを色々と試したところ、それぞれ一長一短があるが**condaを使う方法が一番わかりやすく、実用的**と思われる。
（そもそも個人的にcondaは好きになれずpipenvで仮想環境の管理をしているが、それでもcondaを使うのが楽だった）

ここではdockerを使う方法とcondaを使う方法についてインストール方法を述べる。

## dockerを使う方法

- 利点 : 使うだけなら一番簡単
- 欠点 : 追加のパッケージを入れようとするとつらい

まずはイメージをダウンロードする。このdockerイメージにはgraph-toolに加えて、numpyやjupyterなどがインストールずみ。

```shell-session
$ docker pull tiagopeixoto/graph-tool
```

起動するには以下のコマンドを実行する。

```shell-session
$ docker run -p 8888:8888 -p 6006:6006 -it -u user -w /home/user tiagopeixoto/graph-tool bash
$ jupyter notebook --ip 0.0.0.0
```

これで http://localhost:8888 ブラウザにアクセスすればjupyterが使える。

終わったらCtrl-Cでjupyterを終了し、shellを終了する。
終了してもcontainer自体は残っているので、`docker start <container>`でcontainerを再起動でき、さらに

```shell-session
$ docker exec -it -u user <container> jupyter notebook --ip 0.0.0.0
```

で同じようにjupyterを再度起動できる。

実際に運用する際には、以下のようにして手元のディレクトリをマウントしてしまう方が楽なことが多いだろう。

```shell-session
$ docker run -p 8888:8888 -p 6006:6006 -it -u user -w /home/user -v $(pwd):/home/user tiagopeixoto/graph-tool bash
```

この方法は最初に使い始めるまでは良いのだが、少しカスタマイズしようと思うと難しくなる。
`pip`で追加でパッケージを入れようとしたが、このイメージでは`pip`コマンドが使えなかった。jupyterのnbextensionsなどを導入しようと思ったが、導入する方法がわからなかった。

## condaを使う方法

- 利点 : 他のpackageもcondaで導入しやすい
- 欠点 : pipenvなどの他のツールを使っている場合に統一できない

ここではpyenvを使ってanacondaをインストールする。

```shell-session
$ pyenv install anaconda3-2020.02
$ pyenv local anaconda3-2020.02         # 先ほどインストールしたanacondaを以下で使う
```

続いて、`conda`コマンドでgraph-tool（とその他の）packageをインストールしていく。

```shell-session
$ conda create --name gt -c conda-forge graph-tool          # `gt`という名前の仮想環境を構築し、conda-forgeからgraph-toolをインストールする
$ conda install -n gt -c conda-forge ipython jupyter           # 追加のpackageのインストール場合、このようにする
```

ここで注意点として、必ず`-c conda-forge` をつけて、conda-forgeからパッケージをインストールするように指定する。
またgraph-toolだけでなく、追加のパッケージをインストールするときも同様に`-c conda-forge`を指定するのが良い。デフォルトのAnaconda公式のパッケージとgraph-toolはコンフリクトすることがよくあるようだ。

構築した仮想環境`gt`を使うためには`conda activate`するのが通常の方法ではあるが、`conda activate`コマンドを使うようにするためには`~/.zshrc`を編集したりする必要がある。
あまり既存の環境を変えたくはないので、私は次のようにして`pyenv`を使って環境を切り替えることにした。
`pyenv versions`を実行すると先ほど作った仮想環境が `anaconda3-2020.02/envs/gt` という名前で作られていることがわかる。
そこでこの環境を`pyenv local`などのコマンドで切り替えて使う。

```shell-session
$ pyenv local anaconda3-2020.02/envs/gt
```

### テスト

テストとして、以下のようなテストコードを走らせてみよう。

```python3:hello.py
import graph_tool.all as gt

g = gt.Graph()
v1 = g.add_vertex()
v2 = g.add_vertex()

e = g.add_edge(v1, v2)
gt.graph_draw(g, vertex_text=g.vertex_index, output="two-nodes.pdf")
```

```shell-session
$ python hello.py
```

実行後に"two-nodes.pdf"という名前で以下のような画像のファイルができていたら成功。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28792/0ad6b67f-b846-91fc-d515-66ece42e723a.png)