このシリーズは、Cytoscapeを使ってやIPython Notebook、Pandasなどのオープンソースツールを利用し、公開データを元に実際のグラフ可視化を行う過程を紹介する、可視化の実践者向けの記事です。
Cytoscapeを使った実際の可視化作業の流れ
はじめに
誰にでも馴染みのある公開データを使って単純な例を作ろうと思い始めた今回の作業ですが、思いのほかデータ加工が面倒で、実際の可視化作業の解説まで時間がかかってしまいました。今回はいよいよPythonスクリプトから出力されたデータを使い、ファイル経由でCytoscapeにデータを読み込ませて可視化してみようと思います。
今回利用するソフトウェアとデータ
今回は、前回までに作成したデータとCytoscapeのみを利用します。
ソフトウェア
- Java 7 (現在、Java 8では動かないので注意)
- Cytoscape 3.1.1
データファイル
どれも大きなファイルではないので、加工済みのファイル(前回までに作成したスクリプトの出力)をここに置いておきます:
データを加工する段階から行いたい方は、前回、前々回の記事を参照の上以下のIPython Notebookを実行してみてください。恐らく、あらじめいくつかPythonのライブラリをインストールする必要があると思います。
作業の流れ
- ネットワーク(グラフ)データのCSVからの読み込み
- ノード属性テーブルの読み込み
- 部分グラフの切り出し
- 部分グラフへのレイアウト
- カスタムスタイルの適用
データファイルの読み込み
グラフデータの読み込み
Cytoscapeでは自動的に良い込めるいくつかのスタンダードなファイルフォーマット(GMLやGraphML等)をサポートしていますが、自前でデータを作成する時は、テーブル形式のデータ(Excel, CSV, TSV等)が扱いやすいと思います。前回までに作成したデータが全てCSVなので、今回はそれを使用します。
テーブルからネットワークを読み込むコマンド
File → Import → Network → File
Cytoscapeでは、__Source - Interaction - Target__と言う3つの情報をひとつの単位として一本ののエッジを表します。従って、デフォルトの状態ではグラフは有向グラフとして格納されます。また、__Interaction__と言うエッジのタイプを示す情報を利用するため、同一ノード間に複数のエッジを作成することが可能です。この3つの要素で関係性を表すという設計のため、セマンティックウェブで使われるトリプルで表現されたグラフもそのまま読み込んで関係性を見るといったことも可能です。
テーブルからネットワークを読み込む場合、上記の三要素以外は全てエッジアトリビュート(属性)として読み込まれます。
属性とは?
属性とは、ノード、エッジ、ネットワークに関するあらゆる情報のことを指します。今回のデータセットで言えば、以下の様なものです:
ノード属性
- 駅名
- 緯度・経度
- 一日あたりの乗降客数
エッジ属性
- 路線名
- 路線種別(普通鉄道・モノレールなどの種類)
- 運営会社
- 距離
ネットワーク属性
- 路線図の名前(全国・東京メトロ・近鉄などのネットワーク名)
- 作成日時
- データソースURL
このように、ネットワークの接続情報(グラフトポロジー)以外の全てが属性です。今回は最初のインデックス行を除き、全てをエッジ属性として読み込みます。エッジの三要素を選択したあと、各カラムにチェックを入れるだけです:
読み込ませると、初期状態では下のような図が表示されると思います。(必要に応じてズームイン/アウトして下さい。ズームはマウスホイールに割り当ててあります)
下部の__Edge Table__と言うタブをクリックすると、エッジに各種情報が読み込まれているのが確認できます:
ネットワークとエッジ属性の読み込みはこれだけで終了です。つまりテーブルからデータを読む場合、ネットワークとエッジに関する情報は同時に読み込めます。
ノード情報の読み込み
続いてノード属性を前回作成したテーブルから読み込みます。
テーブル(属性)を読み込むコマンド
File → Import → Table → File
ここで注意する点は一つだけです。それは、__マッピングのためのIDカラムを正しく選ぶ__ことです。ネットワーク読み込みの時、ノードには__駅ID (station_cd)をIDとして利用しました。従って、ノード属性を読み込むにはこれを指定する必要があります。Show Mapping Options__にチェックを入れて、_station_cd_をキーとして選択して下さい。尚、最初のカラムは必要のないDataFrameのインデックスですので、チェックを外して下さい。
読み込み後のテーブルはこのような感じになるはずです。(__Node Table__タブをクリックして下さい)
ネットワーク名の変更
デフォルトの状態では、ファイル名がネットワーク名とネットワークコレクション名に使われます。これをわかり易い名前に変更します。ネットワーク名を右クリックして、ポップアップメニューから__Rename Network...__を選択し、名前を変更します:
同じように、ネットワークコレクション名も変更します:
この状態で、基本的な全国の路線データが読み込まれました。ここまでのデータをセーブします。これは今後、何か他のデータセットと組み合わせたい時もベースとして使える、Cytoscape上の白地図のようなものです。
File → Save
この後の作業で元データをいくら破壊してもいいように、別名でもう一つ作業用のファイルを作っておくと安心です:
File → Save as...
このファイルをベースに作業します。
サブグラフの切り出し
全てのデータがメモリ上に載っているので、キーワードやワイルドカードなどの馴染みやすい文法を使ってノードやエッジを検索することが出来ます。現在一つだけある大きな全国版の路線図から、ある特定の路線を切り出してみます。画面右上のテキストエリアに以下のクエリを打ち込みエンターキーを押したあと、__CTR+N / Command+N (Mac)__で新しいサブグラフとして切り出せます。
line_name:東京メトロ
CTR+N
自動レイアウト
現在切り出したばかりの状態ではバラバラにノードが配置されているので、とても見づらいです。ここに自動レイアウトを施して、見やすくまとめましょう。以下のボタンをクリックすると、デフォルトのレイアウトが実行されます。
だいぶ見やすくなりましたね。この他にも、__Layouts__以下に様々な自動レイアウトアルゴリズムが用意されていますので、一つ一つ適用して結果を比べるとそれぞれのアルゴリズムの性質が分かって理解しやすいと思います。また、レイアウト結果はいつでもCTR+Z (Command+Z)でUndoできます。
Visual Style
以上でサブグラフ切り出しと簡単なレイアウトが終わりました。しかし、これを実際に使える可視化に仕上げるためには、Cytoscapeのコア機能である__Visual Style__と言う機能を使いこなす必要があります。中核となる概念はシンプルです。それは、
属性(データ)が視覚効果をコントロールする
という点です。つまり様々なデータを読み込んだ後、それらの値から視覚効果、すなわちノードの色・形・大きさ、エッジの太さ・色・線のタイプなどへのマッピングを作成し、そのマッピングにより最終的な見た目が決定されるということです。例を挙げると以下の様なマッピングがあります:
- エッジの重みからエッジの太さへ。重みの値が高いエッジを太く。
- グループAに属するノードは赤色に、グループBに属するノードは緑色に。
- 血縁関係にある人々を結ぶエッジは実線に、職場の同僚は破線で
このように、データが最終的な描画を決定するので、データが豊富であればあるだけ様々な可視化の可能性が広がります。ただし、マッピングが多ければ良いというわけではないので、そのあたりは後ほど解説します。
新しいスタイルの作成
__Style__タブをクリックし、プルダウンメニューから__Create New Style__を選択し、新しいスタイルを作成します。ここでは、_metro_と言う名前にします。
スタイルの値の設定には二種類あります。一つ目はマッピングを行われていない要素に適用される__デフォルト値__、そして属性値と視覚効果(__Visual Property__と呼ばれます)を結びつけるマッピングです。
デフォルト値
デフォルト値の概念は簡単です。それは、何もマッピングが指定されていない時に使用される値です。新しいスタイルを作成すると、以下のような見た目が適用されます:
__Def.__以下の値がデフォルト値です。いくつか変更してみましょう。変更は、それぞれの値をクリックするだけです。
- Node Fill Colorを白に
- Node Border Widthを4に
- Node Widthを100に
- Node ShapeをRound Rectangleに
- Edge Widthを5に
指定した値に従ってグラフの描画が変化するのがわかると思います。
マッピング
次はマッピングです。マッピングには__Passthrough, Discrete, Continuous__の三種類があります。順番に解説します。
Passthrough
最もシンプルなマッピングです。これは__属性値をそのまま視覚要素にマッピング__します。例えば、station_nameと言う駅名の属性をラベルにしたいならば、station_nameからNode LabelへのPassthroughマッピングを作成します:
結果はこのようになります
そして、これはCSSのように色の値をそのままノードやエッジの色にマッピングすることも可能です。前回作成した路線のテーマカラーをまず読み込みます:
注意する点は、読み込む時にエッジテーブルに対して追加するという点です。そしてその結果をPassthroughに渡します
エッジの色が東京メトロのテーマカラーになっているのがわかると思います:
このようにPassthroughの考え方はとてもシンプルです。他にも、
- 数値から直接ノードの大きさ、エッジの太さを指定
- 形を表す文字列(_rectangle_等)からノードの形へ
- ビットマップ画像のURLからノード上のカスタムグラフィックス
などがPassthroughに対応しています。
Discrete
次のタイプは__Discrete(離散)マッピング__です。これは、鉄道路線の種別(地下鉄・通常・路面電車などの種別)や運営会社など、カテゴリーを表す値から視覚効果へのマッピングです。わかり易い例として、前回クリークを作成した時に出来たエッジの__Interaction__に0と言う値を持つ「徒歩圏内で乗り換え可能な経路」に特殊な視覚効果を与えましょう。まずは線のタイプです。それらを点線で表します:
同じように太さにもマップを作ります。デフォルトは更に太く10とし、グループ内接続エッジ(interaction=0のエッジ)は3とします:
結果、グループ内のエッジは細い点線に、実際の地下鉄路線は太い色付きのエッジにマッピングされます。
このように、このマッピングは__カテゴリカルなデータを視覚効果にマッピングするのに利用されます__。
上記の例以外にも、以下の様なものが典型的です:
- 私鉄を表すエッジを白に、JRを緑に
- 地下鉄の駅を円に、それ以外を長方形のノードに
Continuous
最後のContinuousマッピングは、__連続する数値を別の数値にマッピングする__仕組みです。簡単な例を作ってみましょう。以下のレイアウトを実行すると、ノードが円形に、ノード次数の順に並べられます:
結果はこうなります:
この時点で、各ノードの次数が__degree.layout__と言う属性として保存されています。この次数をノードの高さと幅にマッピングしてみましょう。degree.layoutを属性に、マッピングのタイプをcontinuousに指定してマッピングを作成し、赤い正方形をダブルクリックすると値(この場合はノードの幅と高さ)を入力できます:
このマッピング指定は、__次数の低いものは小さく、次数の高いものは大きく__という単純なものです。このデータセットにこのマッピングが最適とも言えないのですが、わかり易い例として使います。結果は以下のようになるはずです:
ここで一旦結果をセーブし、自由にレイアウトをいじったり、他のマッピングを試したりして色々と実験してみてください。実際に試すのがまさに「百聞は一見にしかず」で、結果を視覚的に確認しながら機能が理解できるのでおすすめです。
今回作成した実際のサンプルセッションはここにおいておきますので、自由にお使い下さい。様々なマッピングやレイアウトを試しているうちに基本機能が理解できると思います。
とりあえず結果だけ見てみたいという方のためにウェブ版にも書き出しておきました。タブレットでも動くはずです。スタイルをmetroに切り替えてご覧ください:
他のデータを使ったサンプル画像
切り出し方とレイアウトを工夫すれば、それだけでも色々と可視化機能を試すことが出来ます。サーチを工夫して自由に必要なサブグラフを切り出し、それに様々な視覚効果を与えられるように練習してみてください。以下はちょっとしたサンプルです。
小田急線
小田急線をサーチで抽出しサブグラフ化。レイアウトを適用したあと横に90度回転。カスタムレイアウトを適用:
山手線
line_nameで山手線を切り出し、Circularレイアウトを適用。エッジの色はテーマカラーをDiscreteで指定(Line_name → Edge Unselected Paint)。
もちろん、複数の路線をサーチして混在したサブグラフを作ることも容易です。遊んでみてください。
おわりに
Cytoscapeの基本を急ぎ足で見てみましたが、ダラダラと長くなってしまいましたので、ここでいったん分割します。先に作った乗降客数のマッピングは次回カバーします。今回は本当に基本となる部分だけを見たのですが、実際に「良い可視化」を作るには色々と細かなテクニックがあるので、次回はその辺りもカバーする予定です。