Sankey DiagramをRelationで作る

Sankey Diagramでブログ何本書くんだという感じですが...

Tableau 2020.2の新機能であるRelationを使用すると、おそらく一番簡単かつ実用的にSankey Diagramを実装できることに気付きましたので、ここにご紹介いたします。どれくらい簡単かと言うと、過去の記事を全て無かったことにして良いと思うほどに。


今回使用したWorkbookはこちらから。

また今回のアプローチではSankey Diagram描写用のダミーデータを使用します。

こちらからダウンロードをお願いします。


それでは見ていきましょう。

はじめに:Sankey Diagramを作る古典的な方法

今回のアプローチは、実は古典的な作り方とほとんど同じことをします。


Sankey Diagramの実用的な作り方は、自分の知る限り以下のブログが一番古いのかなと思います。

Using Improved Data Connectivity in Tableau 8.2 to Build Sankey Diagrams


この記事の内容を元にして多少の改善が加わった手法が、以下のInformation Labのブログが出るまでは一般的だったように思います。

How to build a Sankey diagram in Tableau without any data prep beforehand

(同じ内容を解説した自分の記事もぜひ:Sankey Diagramをデータ加工なしで作ろう

こちらのブログは「一切のデータ前処理なく」Sankey Diagramが作成できることから注目されました。

つまりそれまでの手法では(これから見ていくのですが)少し厄介なデータ加工を行わなければSankey Diagramは作れませんでした。

まずはその厄介さも含め、古典的な作り方を見ていきましょう。

まず初めに、使用するデータ(今回はSample Super Store)とModel.csv(ダミーデータ)をCROSS JOINさせます。

この結果、各レコードがダミーデータの行数だけ重複します。

SuperStoreデータでRow ID=1のデータを例示します。

古典的方法の一番の問題点は、このレコードの重複です。

今回のModel.csvは約100行ありますが、これはSankey Diagramの作成の為だけにデータを約100倍にすることを意味します。

元々100万行程度のデータなら、約1億行にまで増加しますね。


一方でこの方法を取る理由としては、Sankey Diagram描画のためのデータ点を明示的に作成することができます。

このあたりは後ほど見ていくとして、まずは必要な計算式を列挙します。


Dim 1

[Region]


Dim 2

[Category]


Chosen Measure

SUM([Sales])


Curve Function

1/(1+EXP(1)^-[T])


Sankey Arm Size

[Chosen Measure] / TOTAL([Chosen Measure])


今回の例ではRegion, Categoryごとに、売上構成比を見る場合を想定します。

Sankey Arm Sizeが売上構成比に相当します。


Curve Functionは各Tに対応した、地域0~1での曲線を描くために使用します。

今回はSigmoid曲線を使用しますが、これは正直範囲0~1であればなんでも良いです。


さて、Sankey DiagramではPolygonマークを使います。

つまり以下のように、Polygonの上側と下側を描画させるためのデータ点が必要になります。

このデータ点を作成していくための計算式を見ていきましょう。


Position 1 MAX

RUNNING_SUM([Sankey Arm Size])


Position 1 MIN

[Position 1 MAX] - [Sankey Arm Size]


Position 2 MAX

RUNNING_SUM([Sankey Arm Size])


Position 2 MIN

[Position 2 MAX] - [Sankey Arm Size]


Curve 1-2 MAX

[Position 1 MAX] + ([Position 2 MAX] - [Position 1 MAX]) * MIN([Curve Function])


Curve 1-2 MIN

[Position 1 MIN] + ([Position 2 MIN] - [Position 1 MIN]) * MIN([Curve Function])


Curve Polygon 1-2

CASE MIN([Min/Max])

WHEN 'Min' THEN [Curve 1-2 MIN]

ELSE [Curve 1-2 MAX]

END


計算式はシンプルなので説明は割愛しますが、気になる方は以下の記事が参考になると思います。そちらを参照ください。

TABLEAUでSANKEY DIAGRAMを作る


そして以下のように各要素を配置すれば完成です。

Polygonを使うこと、PathをPathマークに入れることに注意してください。


この古典的な方法はCROSS JOINにより元データのデータ量が増加することを除けば、作成する計算式と設定が必要な表計算の数が少なく済むので、かなり実装がしやすい手法でした。

それでも現在あまり使われていないように思うのは、やはりこのCROSS JOINによる重複が厄介だからかなと。元データを100倍近く増やすのは困るので。

(もちろん事前にSankey用にデータを集計し、集計データに対してCROSS JOINという手もありますが…Sankey用にしか使えないデータソースを作るのは実践的ではありませんよね)


その意味でデータを増加させない手法もう少し扱いやすくした手法を色々と自分含めたTableauコミュニティは考えてきたわけですが、今回はTableau 2020.2の新機能「Relation」を使用して、元データ自体のデータ増加を割けつつも、古典的な(使いやすい)形でのSankey Diagram実装を目指します。

Relationを使用してSankey Diagramを作る

2020.2の新機能(というより新データモデル)であるRelationについて、日本語では以下の記事が詳しいです。

Tableau 2020.2 Data Modeling 機能 (Noodle)の使い方ポイントまとめ


今回使用する要点だけ述べると、リレーションで接続されたテーブルは、そのテーブルの項目が呼び出されない限りは結合されません。

例えば以下の図だと、ビュー上の項目は全てSuperStoreのOrdersから持ってきていますが、JOIN使用(左)では結合後の結果が出るのに対し、Relation使用(右)ではModel.csvの項目が使われていないので、データの結合が起きていないことが分かります。


そしてこの機能をSankey Diagramにどう応用するか。

結論から言えば、データソースをRelationを使用した以下の形に置き換えます。

これだけです。


それ以外は全く変えることなく、同じSankey Diagramを作成できます。


一方で先述の通り、Model.csvの項目を使用しない限りはSuperStoreのデータそのままとして使用できるので「Sankey Diagram専用のデータソース」を作成するというよりは「Sankey Diagramも作成できるデータソース」を作ることができます。

つまり以下のようなダッシュボードを数値の重複を気にせずに作成できます。

(こちらは実際Workbookを見ていただければ分かるのですが、面倒な重複処理など一切していません)


元々の手法の問題点は「元データ自体をCROSS JOINで重複させる」ことでした。Relationを使えばSankey Diagramを作る場合にのみ重複を発生させるので、Data Densification使用したアプローチが目指していた「元データを重複させない」目的もある意味で達成できます。

その一方で計算式はかなり少なくなるので、実践的にSankey Diagramを作るのであれば、この手法が総合的に良いのではと思います。

最後に

何度かSankey Diagramの記事を書いてきましたが、この手法が一番楽だと思います。

一方でRelationが使えないケースでは、Data Densificationによる実装が選択肢にはなりますが…多分レアケースかなと。

前述のように、Sankey用のダミーデータをデータソースに足したとしても、参照されない限りは悪さをしないので、足せるなら足しても良いのかなと思います。


これからSankey Diagramを使う場合は、自分はこの方法で実装すると思います。

ぜひ試してみてください。


質問などありましたらTwitterかLinkedinでお願いします。それでは。