ネットワーク可視化ツール「Cytoscape」を自動操作して楽する話—PowerShellでCyREST-APIを叩く—

すこし前に"ネットワーク可視化ツール「Cytoscape」に雑に入門して手っ取り早く使う話"と題して、オープンソースの可視化ツールCytoscapeに、Excelデータを読み込ませる簡単なやり方について書きましたが、なかなか手数が多いので、繰り返しやる時にはかなり面倒です。

そんな時、面倒な読み込みの手順を自動化して、ワンクリックでさくっとグラフ化できたら最高だと思いませんか?

できるんです。そう、「CyREST-API」ならね。

まずはフワッと概要を紹介するので、御託はいらねえって方は下の「やってみる」まで読み飛ばしてください。

CyREST-APIってなんですか?

Cytoscape REpresentational State Transfer Application Programming Interface」の略です、よくわかりませんね。

意訳すると「Cytoscapeがhttp://localhost:1234にWebサーバーを立ててるから、そこにコマンドを投げればCytoscapeが操作できるよ、使えるコマンドはAPIのリファレンスを見てね」という感じの機能です、だいたい。

f:id:at_you_key:20190426180037p:plain
こんな雰囲気

もう少しおおざっぱに言うと、Webでよく使われている「REST-API」という、アプリ同士を連携させるための仕組みを使って、他ののアプリからCytoscapeを操作できるという仕組みです。

Windows標準環境でCyREST-APIを使いたい

自動操作のインターフェースは見つかりましたが、これをどこから操作するかが次の課題です。

調べるとPythonとかRを使う情報が多いようですが、いま僕が使えるのはWindows7~8環境で、あんまり追加のソフトを入れられないものとします。さあ困った。

Windowsでcurlコマンド?

※このへん僕の理解が曖昧なので、間違いがあれば適宜読み替えてください。

REST-APIってのを使うときは、Linux環境なら元々入っているcurlというツール使うのが簡単そうです。

qiita.com

ところがWindows7~8の場合、標準環境にcurlは入っていません(10なら入ってるらしい)。困った。

そこで登場するのが「PowerShell」です、これはコマンドプロンプトの上位互換?な感じのツールです。

tonari-it.com

PowerShellにはcurlに相当するInvoke-WebRequestというコマンドが用意されていて、しかもなんとエイリアス(名前のショートカット?)が設定されているため、curlと打っても使えます!

やってみよう

さて、ここまでのところは僕もよくわかっていないで書いているので、さっさと実践編に移りたいと思います。

PowerShellの基本的な使い方については、いろいろわかりやすい情報があるので、ここでは解説しません。

とりあえず、PowerShell用の標準の開発環境「PowerShell ISE」を使うのが簡単そうです。

tonari-it.com

前の記事の例題をつかって解説していこうと思います。

at-you-key.hatenablog.com

こんな流れになります。

  • Excelでデータセットを用意する
  • Cytoscapeを起動する
  • PowerShellスクリプトを実行する
  • データセット(Excelファイル)の読み込み
  • レイアウトを適用
  • スタイルを適用
  • フィルターでデータの絞り込み

データセットの列数が14を超えてはいけない

データセットの用意については前の記事の通りですが、CyREST-APIを使うにあたって1つ注意点があって、列数が14を超えると読み込みがうまくいきません。

なにか回避方法があるのかもしれませんが、とりあえず14を超えなければうまく読み込めるようです。

僕はこれのせいでかなりハマりました。

CyREST-APIの立ち上げ

Cytoscapeを起動すればCyREST-APIも有効になります。

Webブラウザでhttp://localhost:1234/v1を開いてみて、下のようなJsonが返ってきたらちゃんと動いています。

{
  "allAppsStarted": true,
  "apiVersion": "v1",
  "numberOfCores": 4,
  "memoryStatus": {
    "usedMemory": 451,
    "freeMemory": 2810,
    "totalMemory": 3262,
    "maxMemory": 6820
  }
}

メニューバーの「Help」→「Automation」にCyREST-APIのリファレンスがあるので、基本的にはここを熟読しつつトライ&エラーで使い方を探っていけば良いと思います。

「CyREST API」と「CyREST Command API」がありますが、呼び出し方はどちらも同じで、前者はアプリ全体の操作系、後者はデータの細かい操作系の機能です、たぶん。

データセットの読み込み

さあ、ここからがPowerShellの出番です。

ちなみに、データセットはC:/temp/nobita.xlsxに保存していることとします*1

「network/import file」コマンド

コードはこんな感じ、Cytoscapeを起動しておいてから実行すれば、たちどころにネットワーク図が表示されるはずです。

$uri = "http://localhost:1234/v1/commands/network/import file"

$body = '{
"columnTypeList": "ea, s, t, ea",
"dataTypeList": "s, s, s, s",
"file": "C:/temp/nobita.xlsx",
"firstRowAsColumnNames": "true",
"indexColumnSourceInteraction": "2",
"indexColumnTargetInteraction": "3",
"indexColumnTypeInteraction": "4",
"startLoadRow": "1"
}'

Invoke-WebRequest -Method Post `
-Headers @{"Content-Type" = "application/json" ;"Accept"= "application/json"} `
-Body $body `
-Uri $uri

sleep 1

コマンドの実行に必要なURIとBodyを変数に格納しておいてからInvoke-WebRequestに突っ込んでいます。

uri

この部分でAPIのアドレスを指定しています、ここではimport fileコマンドを指定していますね。

$uri = "http://localhost:1234/v1/commands/network/import file"

URIってURLとどう違うの?って思ったらこちら webtan.impress.co.jp

body

そして、ここでコマンドの実行に必要な項目を指定しています。

$body = '{
"columnTypeList": "ea, s, t, ea",
"dataTypeList": "s, s, s, s",
"file": "C:/temp/nobita.xlsx",
"firstRowAsColumnNames": "true",
"indexColumnSourceInteraction": "2",
"indexColumnTargetInteraction": "3",
"indexColumnTypeInteraction": "4",
"startLoadRow": "1"
}'

Bodyに何を書けばいいかは、前述のリファレンスを読んでみてください。

一つだけ注意すべきは、"file"の欄に入れるパスに日本語が含まれると、文字エンコードの泥沼にハマるのでお気をつけて。

Invoke-WebRequest

これがAPIにリクエストを送信している部分ですね、前述のとおり「curl」に置き換えても動いてくれます。

オプションが多くて読みづらいってときは、いいところで改行して行末に「`」を付けると、1つのコマンドとして処理してくれます。

sleep

最後の行に処理待ちのタイマーを入れてみました。秒数指定なので、この場合だと1秒待ちです。

sleep 1

もっと良い処理待ち方法があるのかもしれませんが、とりあえず動くのでここはこれで。

実行した結果はこちら。

f:id:at_you_key:20190426180225p:plain
PowerShellの画面

f:id:at_you_key:20190426180235p:plain
実行結果

レイアウトの適用

読み込みができたら、次はレイアウトを変えてみましょう。

今回は見た目の変化が見えやすそうなDegree-circleレイアウト*2を設定してみます。

「layout/degree-circle」コマンド

$uri = "http://localhost:1234/v1/commands/layout/degree-circle"
$body = '{}'
Invoke-WebRequest -Method Post `
-Headers @{"Content-Type" = "application/json" ;"Accept"= "application/json"} `
-Body $body `
-Uri $uri
sleep 1

こっちはだいぶ簡潔ですね。

リファレンスを見るとBodyで設定できるプロパティは色々あるようですが、ぜんぶOptionalなので、とりあえず試すだけなら空欄でも動きます。

ここまでのコマンドを実行すると、画面はこんな感じ。

スタイルの適用とかフィルターとか

ここはまだ手を出せていないので、そのうち試して追記します。

まとめ

PowerShellの実行ボタンを押すたびに、シュバババッとグラフが作られていって爽快です。

今回使った以外にも沢山のコマンドがあって、やりたいこともまだあるので、もう少し知見がたまったらまたそのうち書こうと思います。

*1:パスに日本語が含まれると、文字エンコードの泥沼にハマるのでお気をつけて。

*2:つながっているエッジの数に応じて、6時方向から時計回りにノードを並べるレイアウトです。