Blitzboard を使った簡単なネットワーク構造の可視化

## はじめに

世の中には、気がつかないけれど、ネットワーク状の構造を持っているデータは多数存在します。もちろん、鉄道網や航空路線のように、座標が決まっているネットワークは想像しやすいでしょう。他にも、家系図のような階層構造があるもの、SNSの友人関係も、同様にネットワークとして扱われるものです。

ところで、それ以外にも、**対応関係が決まっているものの集合**というのも、ネットワーク構造、あるいはノードとエッジのグラフ構造に擬して扱うことができます。例えば、「赤ワインに合うチーズの一覧、白ワインにあうチーズの一覧」というものは、一見すると単なる一覧表のように考えがちですが、これもネットワークのような構造として扱うことができます。

http://www.wineandcheesemap.com

上のサイトのように配置することで、白ワインとの親和性の高いチーズ、あるいは他のチーズと類似性の高いチーズを一目で見つけることができます。このように、データをグラフの形で可視化することによって、さまざまな種類のデータに対して、新しい気づきを促す可能性があります。

しかし次に問題になってくるのが、このようなデータの可視化を簡単に行うのは、なかなか難しいということです。例えばエクセルで先ほどのような対応関係のテーブルを作ったとしても、折れ線グラフ、棒グラフといった一般的な可視化はできても、ネットワークのような関係性をみるような可視化はなかなか難しいです。特に難しい理由として、ノードとエッジのとして可視化した場合に、どうしてもそのノードが何か、エッジが何かという詳細情報を見たくなるので、インタラクティブな可視化が必要となってしまうことが挙げられます。

https://sandbox.blitzboard.io/

Blitzboard は、**ノード・エッジで表現されるグラフを、インタラクティブに可視化するオープンソースの web アプリ**です。Blitzboard を使うことで、手元にあるちょっとしたデータを、ノード・エッジで構成されるグラフのフォーマットに整形してあげるだけで、簡単に・高速に可視化することができます。

![00E734F1-80AF-4D04-88AB-65DBDCE40468.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92155/88f00d0e-5327-2662-50e2-426d4d7a774c.jpeg)

それでは、ここでは実際に Blitzboard でどんなことができるかについて、簡単な例を使って紹介してみたいと思います。


## 下準備

左側のテキストフィールドに、グラフを定義します。元から入力されている例で示されているように、グラフ構造はテキストベースの構造で表現されています。このフォーマットは PG フォーマットと呼ばれますが、**PG フォーマットはめちゃくちゃ簡単なので、深いことを考えずに記述することができます。** 例えば、ノード1とノード2があって、その間にエッジを引こうと思うと、以下のように表現することができます。

```
Node1 -> Node2 :edge_label

Node1 :node_label
Node2 :node_label
```

このようにテキストフォーマットであるため、任意のプログラミング言語を使ってデータを整形することが容易にできます。雑に言ってしまえば、対応関係を矢印（`->`）で結んでテキストに出力すれば良いということになります。詳しい仕様を知りたい場合は、下記サイトに仕様が掲載されていますが、仮に少し定義から外れた記述をしてしまったときでも、どこで文法エラーが発生してくれるか Blitzboard 上で教えてくれるので、それに従って直していくだけでもそれほど困らずに習得することができると思います。

https://pg-format.readthedocs.io/en/0.4/contents/pg-format.html

PG フォーマットの嬉しい点をいくつか紹介します。

* テキストフォーマットであるため、任意のプログラミング言語を使ってデータを整形することが容易にできます。
* 順序の依存性がないので、エッジを先に全部書き出した後で、ノードを定義するといった順番に書いても問題ありません。
* [pg tools](https://github.com/g2glab/pg)を使って、 neo4j などのグラフDBに登録できるようなフォーマットに変換することができます。

今回は、将棋のプロ棋士同士の対局結果の1ヶ月分の一覧に対して、勝った棋士から負けた棋士に対してエッジを貼るというやり方で、pg フォーマットのグラフデータを生成しました。



![93D6C9F4-9953-4FA9-B7FD-8B16854AA2D3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92155/6c3573e9-5fc9-9fcd-bb03-1c17973237af.jpeg)

pg フォーマットにしたデータを解析するために neo4j などのグラフデータベースに登録するというの1つ方法でしょう。しかし、ちょっとした可視化をしたい場合に、そのような大仰なことをするのは大変です。そこで、 Blitzboard の出番です。 Blitzboard は web アプリなので、ローカルでインストールなど作業することなく手軽に可視化できます。

それでは、ここで作ったデータを Blitzboard に投入してみましょう。**普段は単なるテーブルデータとしてみるようなデータを、ここでグラフとして表現してみるとどうなるでしょうか？**

## ノードのアイコンを変えてみる

![7411F471-EE5E-4892-9777-C8704F1FD7FB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92155/da2b5fac-4b52-cabb-db98-579b91b4645e.jpeg)


見た目など、さまざまな調整を行いたい場合は、必要な情報をあらかじめ PGフォーマットで定義しておくだけで、インタラクティブに設定を変更することができます。

現状で、ノードのアイコンは全て青い円になっています。これを、人型のアイコンに変えてみましょう。


まず、歯車マークのボタンを押下します。するとメニューが開きます。

![FB34D7F4-C124-428F-A7A7-5CFAF0C386AC.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92155/60275d3c-baa5-4285-a406-2ede7fd84413.jpeg)



その次に Show config にチェックを入れます。すると、左下にコンフィグを設定する json ファイルが表示されます。この node セクションを、以下のように書き直してみましょう。

```javascript
node: {
    caption: ['id'],
    defaultIcon: true,
    icon: {
      'player': 'carbon:person',
    },
    color: {
      'player': 'green',
    },
}
```

今回は、それぞれの人にはすべて `:person` というラベルがついているので、person というラベルの場合に、色を緑色にして、人のアイコンが表示されるように変更してみます。ちなみにアイコンは、[iconify](https://icon-sets.iconify.design) から選ぶことができます。

すると、以下のようになります。

![1DA14B23-8CAD-4A0F-8350-581D25999248.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92155/a3febb38-a00f-f42c-0a8a-a946a71fa76a.jpeg)


## エッジに表示させるラベルを変えてみる

現状では、全てのエッジに表示されているのは、 `:win` というラベルになります。それは、config のデフォルトとして、エッジのラベルが表示される設定になっているということと、エッジのラベルとして、全てに `:win` を付与したからそうなっているのですが、それではいささか情報量が少ない気がするので、具体的な棋戦名が表示されるように変えてみましょう。

先ほどの option のところで、 edge: という項目の中身を以下のように改変します。


```javascript
edge: {
    caption: ['match', 'label'],
    width: 1,
    opacity: 0.5,
},
```

![39913B6B-1DE5-4058-94B9-1B820079633A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92155/c15d3466-8ea9-3021-e1b4-aae6b61c385c.jpeg)


## エッジの色を変えてみる

次に、エッジの色を変えてみましょう。デフォルトでは、エッジはすべてグレーで表現されていますが、エッジごとに特徴が違うことから、色を変えて区別してみたいと思います。色を塗る仕組みとして、エッジ全てに対して適用される場合と、特定のキーを持つエッジだけに適用される場合、またキーによって色を塗り分けるといった場合が考えられます。

* `{color: "@color"}` となっている場合は、エッジ color プロパティで設定した色で塗られます。
* `{color: {key: "black"}}` となっている場合は、key で指定したキーを持つエッジに限って、value で指定した色（ここでは black ）で塗られます。
* `{color: {key: "@color"}}` となっている場合は、key で指定したキーを持つエッジに限って、エッジの色をその指定したキーの値で塗られます。（どの色が塗られるかは、ここでは color プロパティに依存します。）

したがって色を塗り分けたいと思った時、プロパティの文字列に応じて勝手に色を塗ってくれるというわけではないので、前処理の段階でエッジに color プロパティを割り振っておいたと言うわけです。

https://docs.blitzboard.io/visualization/edges

edges の設定は、最終的に以下のようになりました。

```javascript
edge: {
    caption: ['match', 'label'],
    width: 1,
    opacity: 0.5,
    color: "@color",
},
```

このようにすると、エッジが色に反映されるようになります。


## まとめ

最終的に、このようなグラフになりました。

![00E734F1-80AF-4D04-88AB-65DBDCE40468.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92155/88f00d0e-5327-2662-50e2-426d4d7a774c.jpeg)

このようにして作ってみると、グラフ上に以下のような構造が現れてくることがわかります。

* タイトル戦で番勝負をしている棋士の間には、エッジが複数本引かれる。
* 王将リーグのような、参加棋士の少ないリーグ戦では、そのリーグ戦の対局者同士の間で密にエッジが引かれる。

結果として、 **単にテーブルデータとしてみるよりも、どの棋士とどの棋士がよく対局しているか？それはどうしてか？といったことを、一目でみることができるようになりました。**


### Future work

また将来的には、以下のような構造が見えてくると期待できます。

* 表示するエッジを棋戦ごとでフィルタすることによって、棋戦ごとの特徴をグラフで観測することができる
    * リーグ戦では、同じリーグに属する棋士がクラスタとして現れる
    * トーナメント戦では、勝ち抜いた棋士からエッジが順に引かれる、階層的な構造として現れる
* 今回は対象としていませんでしたが、引き分けの場合（将棋では千日手、持将棋がこれに該当する）をエッジとして追加することで、引き分けが発生しやすい棋士や組み合わせを観測できる

Blitzboard では、グラフのレイアウトを、force layout だけでなく、 hierarchical なレイアウトもサポートしているので、どのような視点からグラフを見たいか？に応じて、レイアウトを切りかえることができます。

このように、グラフ可視化を通して、さまざまな角度、視点での可視化ができる可能性があります。**手元のデータを、どのようなグラフに変換したら新しい見方ができるかを考えてみると面白い**ですね。