157
150

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

鉄道路線データをグラフとしてCytoscapeで可視化する 4: 東京メトロのデータを例に

Last updated at Posted at 2014-09-08

はじめに

このシリーズは、Cytoscapeを使ってやIPython NotebookPandasなどのオープンソースツールを利用し、公開データを元に実際のグラフ可視化を行う過程を紹介する、可視化の実践者向けの記事です。

最終回は、グラフ可視化で重要なレイアウトとスタイル設定、そしてCytoscapeで作成したデータの他のアプリケーションでの利用について紹介します。

東京メトロのアプリコンテスト

このシリーズでは、どなたにも馴染みのあるデータとして鉄道路線図のグラフデータを例として利用しました。全くの偶然ですが、まもなく東京メトロが運行状況などの各種情報をJSON-LDとして公開し、アプリケーションコンテストを行うと発表しました:

これはコンテスト参加者しか利用できないデータなので、真の意味でのオープンデータではないのですが、それはまあ今後に期待ということで。せっかくなので、先日作成した東京メトロのデータセットを例に、レイアウトやスタイリングでどのように見え方が変わるのかを紹介したいと思います。ここで作成した基本的なグラフ可視化結果にAPIから取得した各種データを各種視覚変数にマッピングすることで、最終的なアプリケーション作成の前に、基本的なデザインやレイアウトを確認するのにも使えると思います。まだデータの詳細が発表になっていないので、コンテストで利用できる実際のデータを使用することは出来ませんが、可視化の方針が路線図データを元に、そこへ各種情報、すなわち電車の位置、遅延、時刻表等をマッピングするというものでしたら、ここで解説してある基本的なここで解説してある基本的なテクニックは、実際のデータでも問題なく利用できると思います。

また最後に触れますが、私達のプロジェクトで作成しているネットワーク可視化JavaScriptライブラリのCytoscape.jsや、D3.jsのForceレイアウトで利用できるJSON形式でデータを書き出すことも可能ですから、最終的に作成するウェブアプリで利用するデータの作成ツールとしても使えます。

レイアウトとスタイルを使いこなす

グラフ可視化において、各種アルゴリズムを利用した自動__レイアウト__とデータを視覚変数にマッピングする__スタイル__の作成は重要なステップです。今回はこれをCytoscapeでどのように行うかを見ていきます。

利用するデータセット

手元で実際に試せるように、前回までに作成したデータを元にしたCytoscape用のセッションファイルを用意しましたので、これを使います。統合した全国版のデータを、東京メトロの部分だけ切り出したものです:

スタイル作成

Review: スタイルとは?

Cytoscapeでは、可視化に使われるマッピングの集合を__Visual Style__と呼んでいます。これは2つの要素に分解できます:

  • デフォルト値 - 何のマッピングも存在しない時に使われる値
  • マッピング - データから視覚変数(Cytoscapeでは__Visual Property__と呼ばれます)への変換

この2つを上手く調節して行くことにより最終的な可視化を作成します。

実際のスタイル作成

今回の可視化のテーマは、ビギナー用の簡単な例として__「銀座線、丸ノ内線、東西線の各駅の2012年度の一日あたりの平均乗降客数を見やすく提示する」__とします。このゴールに向かってレイアウトとスタイルを決定していきます。

まず上のリンクからダウンロードしたセッションファイルを開くと、必要最小限のマッピングが設定されたデータが表示されます:

minimal_style1.png

この状態では何のデータかよくわかりませんね。ここでは、ほとんど何のマッピングも設定されていません。ここから必要な値を設定することにより、より分かりやすい見た目に加工していきます。まずは「過剰な装飾を避けるため、本当に必要のある視覚要素以外は極力削ぎ落とす」と言う方針に則り、ノードの境界線(Nord Border)を削除したいと思います。これは、_Node Border Width_のデフォルト値をゼロに設定するだけです(Def.以下にある四角いエリアをクリックすることで値を入力できます):

border1.png

すると見た目は以下のように変化します:

minimal_style.png

この「白地図」に各種データをマッピングしましょう。

Passthrough Mapping

このサンプルでは、予め一つだけマッピングが設定されています。それは、駅名(station_name)と言うデータからノードラベル(Node Label)と言う視覚変数へのPassthroughマッピングです。前回も触れたように、Passthroughは単純にデータの値を視覚変数にそのまま渡すだけです。つまりこの場合は、「station_nameと言うカラムに存在する値を、そのままノードのラベルとして描け」と言う意味です。

ではここで実際にこのタイプのマッピングを設定しましょう。今回のデータは、前々回に収集した路線ごとの色データ(_line_color_と言う名前のカラム)も含みますので、それを使ったPassthroughマッピングを設定します。

  • __line_color__から__Node Fill Color__へ
  • __line_color__から__Edge Stroke Color (Unselected)__へ

colorpt1.png colorpt2.png

すると、16進数で指定された色がそのままノードとエッジの色に反映されます:

minimal_style2.png

デフォルト値の変更

次はマッピングの必要のない要素の初期値を調整することにより、全体をより見やすく調整します。

  • ノードの形を円形に変更 - Node Shapeを_Ellipse_(楕円)に。
  • 路線図らしく、各路線を太い線で表現 - Edge Widthを20へ。

これで見た目は以下のように変化します:

minimal_style3.png

ではここで一度自動レイアウトを適用して繋がりを見やすくしましょう。ここでは、yFiles社の開発したプロプライエタリな自動レイアウトアルゴリズムであるOrganicレイアウトを使ってみます:

organic.png

metro_layout1.png

ここでは駅の配置は純粋にグラフとしてのつながりを元に計算されていますので、地理的な位置などは一切考慮されていません。

Discrete Mappingによる乗り換え可能を示すエッジの区別

第二回で、元となったデータ内に含まれている駅グループの情報を用いて、乗り換え可能を表すエッジを追加しました。これを他のエッジと区別するマッピングを作成します。これには__Discrete Mappingを使用します。Interaction__と呼ばれるエッジのタイプを示すカラムを使い、ここに含まれる__0__と言う乗り換え可能を表す値に細い点線を表示するようにマップします。すなわち、

  • Interactionの値が0ならば:
    • Edge Line Typeを点線に
    • Edge Widthを2に

と言う簡単な命令をDiscreteマッピングで作ります:

スクリーンショット 2014-09-07 20.31.43.png スクリーンショット 2014-09-07 20.31.58.png

これにより、他のエッジに比べて、徒歩での乗り換え可能を意味する特殊なエッジが細い点線で表示されます:

minimal_style4.png

レイアウト

ここでは、自動レイアウトがどのようなものかを試してみましょう。以下は、Layoutメニュー以下から選択できる各種自動レイアウトアルゴリズムをこの東京メトロのネットワークに適用したものです:

Circular

円形にノードを配置するレイアウト。とても単純なアルゴリズムなので、大規模なネットワークにも利用できます。
circular.png

Force-Directed

いわゆる力学モデルを利用したアルゴリズムで、ネットで見られるグラフ描画のサンプルの多くはこれでレイアウトしてあります。多くの場合うまく行くのですが、大変重い計算なので、大規模グラフには非常に長い時間を要します。
force-directed.png

Hierarchical

階層的な構造を持ったデータに適しますが、そうでないものも強引にツリー状に並べることも可能です。
hir.png

レイアウトアルゴリズムの選択

どのレイアウトアルゴリズムを選択するかは純粋に最終的な可視化をどのようなものにしたいかというゴールによります。一般的に、このような地理データに対して自動レイアウトを行えば、地図上での位置関係は失われます。しかし、抽象化された接続図と言う物を可視化し、そこに各種データをマッピングするのならば、実際の位置関係よりも、以下の様な抽象化されたモノのほうが都合のいい場合が多いです。


(東京メトロの作成した丸ノ内線の手書き路線図)

その場合、__選択した部分ごとに各種レイアウトを利用し、データマッピングに適した形に仕上げる__のがベストです。

マニュアルレイアウト

この他にも、手動で微調整を行うときに利用するマニュアルレイアウトと言う機能もあります。Illustratorをお使いの方ならお馴染みの、指定したオブジェクトを整列させたり、拡大、回転などを行う機能です。後ほど例の中で使用します。

数値を視覚変数にマッピングする: Continuous Mapping

ここでは、今回のメインである乗降客数を利用するマッピングを作成します。安直ですが、2011年度の乗降客数を以下のVisual Propertyにマッピングします。

  • ノードの大きさ
  • ラベルの文字の大きさ

ここでは乗降客数という数値を大きさに変換するので、Continuous Mappingを使用します。以下のように、最大値と最小値に対してマッピング先の値を指定することにより、シンプルな線形のマッピングを作成できます:

cont1.png

cont2.png

結果、乗降客数が多いほど大きなノード、大きなラベルで表示される図が作成されます:

cont_final.png

サブグラフ切り出しと加工

ここで、最終的に必要な三路線を切り出します。検索窓に以下のクエリを打ち込んでエンターを押すと、目的のノードが選択されます:

銀座線 OR 丸ノ内線 OR 東西線

と入力して、CTR+N (Macの場合はCommand+N)で切り出せます。これにyFiles→hierarchicレイアウトを適用すると以下のようになります:

comparison1.png

ここからの仕上げは手動で作業を行います。プルダウンメニューから__Copy Style__を選んで、新しいスタイルをこのサブグラフ向けに作成しましょう:

copy.png

スケーリング

横軸が詰まりすぎているので、幅を広げて見やすくします。__Layout → Scaling__で表示されるパネルを利用します。X軸方向のスケーリングを選択し、見やすくなるように8倍程度まで広げます。ちなみに、Reset scale barをクリックすれば、そこからまた拡大できるので、いくらでも大きく出来ます。

scaling.png

ラベル位置の変更

ラベルを見やすい位置に移動します。これは__Node Label Position__というVisual Propertyのデフォルト値を変更することで行います。デフォルトの状態では表示されていないと思うので、まず__Properties__の一覧から選んで表示させます:

prop.png

そして位置をドラッグ&ドロップで決めたあとに、X方向のオフセット値で微調整します:

labelpos.png

整列

拡大することにより各路線がずれてしまっていると思うので、これを修正します。路線ごとにドラッグで選択して、__Aligh & Distribute__のパネルから縦方向の串刺しアイコンを選べば自動整列します:

aligh.png

必要に応じて細部を調整して、最終的には以下の様なものに仕上げます:


(ハイレゾ版はこちら

簡単な描画ですが、とりあえずどの駅が乗降客が多いか、をざっと把握することは出来ると思います。なお、データの無い駅については小さく表示して混乱を招かないようにしてあります。

これはマッピング機能(Visual Style)を学ぶための単純な可視化の一例に過ぎませんので、上のリンクからダウンロードしたセッションを色々といじってみて、マッピングをどう変更するとそれがどう可視化に反映されるのかを調べてみてください。以下は同じセッションから作った別のサンプルです:

(full res)

(full res)

Webアプリケーションとの連携

spa.png

Cytoscapeでこういったスケッチを作成した場合、何も画像としてのスケッチだけで終わらせる必要はありません。私達の長期的なビジョンとして、今存在する様々な著名ツール(D3.js、Pandas、igraph等の可視化や解析のためのツール群)との連携は重要な項目の一つで、できるだけ一般的な形式でのデータ書き出しをサポートしています。

Cytoscape.js用JSON形式への書き出し

Cytoscape.js形式のJSONとしてネットワークとスタイルを書き出すことが出来ます。これらは直接Cytoscape.jsでレンダリング可能です。また、これらはシンプルなJSONファイルに過ぎませんので、ちょっとした処理を加えれば、他の様々なアプリケーションで利用できると思います。

どうやってJavaオブジェクトをCytoscape.js用のJSON形式にしているのか?

CytoscapeはJavaで書かれたデスクトップアプリケーションで、ネットワーク、テーブル、そしてスタイルも全部Javaオブジェクトです。これらをそのままJackson等のデータマッパを使ってもCytoscape.js形式には上手く変換できませんので、書き出しはカスタムシリアライザを作成してJSONを作っています。特にスタイルは、Cytoscape.jsのCSSのセレクタ形式に各マッピングを変換するため、マッピングの設定によってはとても効率の悪いセレクタが生成されます。JSON形式へのスタイル書き出しを行う場合、Passthrough形式で指定したものが最も効率のいいセレクタを生成します。これはCytoscapeで可視化を作成するときのベストプラクティスではないのですが、最終的にはCytoscape.jsでの利用を考えている場合、これは頭の隅に置いておくと良いでしょう。

D3.jsのForce形式での書き出し

このAppを使うことにより、D3.jsのForceレイアウトで直接使えるデータ形式に書き出すことも可能です。

D3.jsとグラフデータ

D3.jsには「元になるデータのフォーマットに関する制約は最小限にする」と言う思想があるようです。基本的にはCSVなどのテーブル形式でデータを用意すればほとんどの場合はそのまま読み込めます。そんな中グラフ形式のデータに関しては、並び順(ordinal)をIDとみなすという、冗長性は少なくなる一方、若干可読性に欠ける方式となっています。もちろんそれでもシンプルなので、ちょっとしたスクリプトを書いてしまえば済む作業ですが、目で見ながらグラフィカルにグラフ構造をエディットし、それを自動的に書き出せたらそれも便利です。D3.js Exporterは、Cytoscape上で動くプラグイン(App)で、読み込まれたグラフのトポロジと属性データをそのままD3.jsで読み込める形式に書き出すものです。

D3.jsで簡単に読める形式への書き出し

Appをインストールしたあとは、__File → Export → Network__で、ファイル名を指定してD3.js形式のフォーマットを選択するだけです。書き出しの結果はこんな感じになります

D3.js側の基本的なコード

D3.js上で、このJSONに含まれるデータを使ったマッピングを作るのは簡単です。例えば、2012年度の乗降客数データをそのままノードの大きさにマッピングする場合、返り値を半径にマップするだけです:

node.append("circle")
    .attr("class", "node")
    .attr("r", function(data) {
        return data.passengers2012;
    });

この辺りは大量にサンプルが出回っているので、D3.jsとForce Layoutで検索してみてください。D3.jsで可視化を作成する場合、D3.jsでデータを準備したり加工するのはナンセンスですから、IPython Notebook, Pandas, Cytoscape辺りを組み合わせてデータの下準備をしておくと便利だと思います。D3.js側でのコードは上記のようなマッピングや、トランジションといった部分に集中できますので。

D3.jsの使いどころ

リンクした下の例を見ていただければお分かりになると思いますが、JavaScriptでグラフ(ネットワーク)を描画する、と言うだけでしたら、Cytoscape.jsなどを使う方がはるかにコード量も少ないですし、APIの抽象度も高レベルで簡単です。しかし、単なるnode-link diagramを超えた新しい可視化を試したいような場合は、D3.jsのローレベルさが逆に便利です。例えば、D3.jsのTransitionを上手く使って、node-link図とTreemapを切り替え可能にしたりといった場合です。また、D3.jsはデフォルトではSVGで描画する場合がほとんどでしょうから、最終的な出力が紙などの場合もこれは便利な点です(Cytoscape.jsを含むグラフ可視化ライブラリのほとんどがCanvasを利用していますので)。

Single Page Applicationとしての書き出し

これはまもなくリリースされるCytoscape 3.2.0の新機能なのですが、バラバラにJSONファイルを書き出す代わりに、プリセットのWebアプリケーションとして書き出す機能があります。要するに、サーバにそのフォルダごとアップロードすれば、Cytoscapeで作った可視化をそのままウェブアプリケーションとして共有できるという機能です。要するに、既存のCytoscape.js向けJSONシリアライザの出力を一つのzipファイルにまとめて、更にその中にCytoscape.js、AngularJSなどを使ったJSコードとCSS、HTMLをまとめて書き出す機能です。解凍してそのディレクトリに入り、

python -m SimpleHTTPServer 8000

とでもタイプすれば、そのままSPAとしてCytoscape側で作業していた結果をブラウザで再現できます。

もちろん、レンダリングの詳細部分でCytoscapeとCytoscape.jsは異なる部分もあるのでまだ100%の再現性とは行かないですが、これは今後も順次アップデートしていき、再現性をあげます。Webアプリケーションとの連携機能はまだまだ今後増えると思いますが、今の段階でも、Cytoscapeでスケッチしたグラフ可視化をWebアプリケーションで再利用する道は用意されています。


おわりに

これは様々な可視化が可能なCytoscapeの機能のほんの一部です。また機会があったら書いてみようと思うのですが、現在、CytoscapeをREST API経由で操作できるようにするモジュールも開発中で、これが完成すれば、日常的にIPython NotebookやRStudioを利用されている方が、それらのコマンドラインから離れることなく可視化を作成できるようになると思います。

また、可視化一般の知識は別の連載にまとめましたので、こちらも合わせて読んでいただくことにより、理論と実践の関係(とギャップ)を理解していただけると思います:

今後もできるだけ日本語での情報提供を続けたいと思いますが、最新の情報はどうしても英語になってしまいますので、ご興味のある方はぜひ我々の公式ツイッターアカウントや、メーリングリストをチェックしてみてください:

また簡単な質問なら、私に日本語でTweetしてもらっても構いません。皆様が様々なプロジェクトでCytoscapeを活用してくだされば幸いです。

Keiichiro Ono

157
150
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
157
150

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?