PGXからGraphMLで出力しCytoscapeで描画する

# はじめに
###本記事について
PGX (グラフ分析エンジン、Parallel Graph AnalytiXの略)は、単体では描画機能を持ちませんが、グラフの可視化には特徴を掴みやすくなったり、他者との認識を共有しやすくなったりと多くの利点があります。そこで、PGXでグラフデータを分析した結果も含めてGraphMLとしてエクスポートし、そのファイルをCytoscapeで描画する手順を記載します。

### 動作環境について
- [PGX 2.7](https://www.oracle.com/technetwork/oracle-labs/parallel-graph-analytix/downloads/index.html)
- Cytoscape 3.2.1

# PGXでグラフ分析してCytoscapeで描画する
### CSVファイルをPGXにロードし分析
[Oracle Labs発！ Parallel Graph Analytics (PGX)](https://www.slideshare.net/oracle4engineer/oracle-labs-pgx)に記載の手順と"ほぼ"同じです。差分は後述します。PGXのセットアップ方法についてもそちらをご参照ください。

以下ファイルを用意します。

```php:hero-network.csv.json
{
  "uri": "hero-network.csv"
, "format": "edge_list"
, "node_id_type": "string"
, "separator": ","
}
```
「hero-network.csv」は以下のようにコミックで協演したことのあるキャラクター同士をCSVで記載してあるだけのファイルです。

```php:hero-network.csvイメージ
"キャラクターA","キャラクターB"
"キャラクターA","キャラクターC"
"キャラクターB","キャラクターC"
```
この"edge_list"フォーマットも含めたPGXにロードできるファイルフォーマットはPGX Documentの[こちら](https://docs.oracle.com/cd/E56133_01/2.7.0/reference/loader/file-system/plain-text-formats.html)に記載があるので分析対象データのフォーマット検討時に適宜ご参照ください。

PGXを起動し対象データをロードします。

```
$ pgx
（略）
variables instance, session and analyst ready to use
pgx>
pgx> G = session.readGraphWithProperties("/home/oracle/work/hero/hero-network.csv.json")
※有向グラフです（上述の参考スライド上では無向グラフとなっています）

  // 前処理を施します
pgx> G.simplify( \
      MultiEdges.REMOVE_MULTI_EDGES \
    , SelfEdges.REMOVE_SELF_EDGES \
    , TrivialVertices.REMOVE_TRIVIAL_VERTICES \
    , Mode.CREATE_COPY \
    , null \
    )

  // PGQLを実行しPGXにロードできていることを確認します。
pgx> G.queryPgql(" SELECT x WHERE (x) ").print(10)
+------------------------------------+
| x                                  |
+------------------------------------+
| PgxVertex[ID=MELTER/BRUNO HORGAN]  |
| PgxVertex[ID=KALA]                 |
（略）

  // PGXのK-coreアルゴリズムを例として実行します
pgx> analyst.kcore(G)
==> (Scalar[name=scalar_long_9,type=long,graph=hero-network3_2],VertexProperty[name=vertex_prop_long_8,type=long,graph=hero-network3_2])
  //↑ノードのプロパティに"vertex_prop_long_8"というプロパティで値が格納されました

  //プロパティが追加されているか確認します
pgx> G.queryPgql("SELECT x, x.vertex_prop_long_8 WHERE (x)").print(10)
+---------------------------------------------------+
| x                          | x.vertex_prop_long_8 |
+---------------------------------------------------+
| PgxVertex[ID=PREYY]        | 16                   |
| PgxVertex[ID=RAMONDA]      | 12                   |
（略）
```
GraphMLにエクスポートします。

```
pgx> config = G.store(Format.GRAPHML, "/tmp/hero.graphml")
```
　※無向グラフはエクスポートできませんでした

### GraphMLをCytoscapeにインポート
Cytoscapeを起動し、"File"タブからたどり"File..."を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120705/64f1ee5d-7aa9-8411-3283-785ea6a7dafd.png)

表示されるダイアログにはそのまま"OK"を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120705/8d744076-22ab-4e0d-8087-50038283ee8b.png)

対象のGraphMLを選択すると、以下のように描画されます。画面下部の"Table Panel"欄より、先ほどノードに付与されたプロパティもCytoscapeにインポートされていることが分かります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120705/05cb22b9-213a-f479-6425-6e7dec46f1cb.png)

このままではグラフやノードの特徴を把握しにくいため、適宜"Control Panel"で描画Styleを変更します。
プロパティのデータ型が数字で連続データの場合、"Continuous Mapping"で値の大小に応じたグラデーションの設定ができます。個人的に好きな描画Styleです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120705/c63db61c-f6f5-4d93-c15f-94dc123faf2e.png)

以下のようにプロパティ値に応じてノードの濃淡が表現されるため、目的に応じたノードが見つけやすくなったり、グラフの特徴を感覚的に把握しやすくなると思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120705/a9576c38-2aec-5595-c4bf-9fac786590c3.png)