2019年4月20日

TableauでHexbin Mapを作る

今回のテーマはHexbin Mapです。

以下のViz作成を通して解説します。

リファレンスは以下です。

https://www.youtube.com/watch?v=PuReHF8H_n8

https://www.youtube.com/watch?v=JM3u0RSd35Q

Tableau Workbookは以下からダウンロードできます。

https://public.tableau.com/profile/yoshitaka6076#!/vizhome/BlogHexbinMap/Sample

今回のデータは以下を使用します。

https://data.world/lukewhyte/us-population-by-zip-code-2010-2016

https://public.opendatasoft.com/explore/dataset/us-zip-code-latitude-and-longitude/export/


【Hexbin Mapについて】

詳細は以下の記事をご参照下さい。

https://vizhacker.net/data/tableau/741/

ざっくり説明すると、郵便番号のような粒度の細かいデータが大量にある場合、地図がとてもmessyな感じになってしまうので、隣接するものを適度にまとめて、地図を見やすくする方法です。

ところでこのHEXBIN関数を用いたHexbin Map、マークタイプがShapeなので、このヘキサゴンの大きさはSizeの調整によるところが大きいです。

どういうことかというと、ちょっとズームすると、もうスカスカなんですよね。

これをColor横のSizeで調整しなければいけない、という状態が生じます。

これを解決するために、Data DensificationとPolygonを使用して、Hexbin Mapを作成します。


【Popygon Hexbin Mapの作り方】

今回の使用データを以下のようにINNER-JOINさせます。

まず、下記の計算フィールドを作成します。ここでHexbin Sizingは整数型パラメータです。

Measure

[y-2016]

Hex Latitude

HEXBINY([Longitude]*[Hexbin Sizing],[Latitude]*[Hexbin Sizing])

/ [Hexbin Sizing]

Hex Longitude

HEXBINX([Longitude]*[Hexbin Sizing],[Latitude]*[Hexbin Sizing])

/ [Hexbin Sizing]

ここからヘキサゴンのPolygonを作成するため、以下の計算フィールドを用意します。

Paddingからはサイズ1のBinを作成します。

Padding

IF [zip_code] = { FIXED [Hex Latitude],[Hex Longitude] : MIN([zip_code])}

THEN 1 ELSE 6 END

Angle

PI()/3 * INDEX()

これらを使用して、下記の計算フィールドを作成します。

Polygon Hex Latitude

WINDOW_MIN(MIN([Hex Latitude])) + SIN([Angle])/[Hexbin Sizing]

Polygon Hex Longitude

WINDOW_MIN(MIN([Hex Longitude])) + COS([Angle])/[Hexbin Sizing]

Measure (Polygon)

WINDOW_SUM(SUM([Measure]))

ここでそれぞれの表計算はPadding(bin)を使用するように設定してください。

さて、ここでいくつかの計算フィールドの補足をします。

HEXBIN関数の本質は、地図上の点をまとめ上げることでした。

今回の場合は、あるHex Latitude/Longitudeに、複数のzip_codeが含まれることになります。

Polygon Hex Latitude/Longitudeは、そのzip_codeの集合の中心点からsinとcosで六角形の頂点を与え、その頂点に沿ってPolygonを描写します。

Measure (Polygon)は、そのPolygon内に含まれるMeasureを全て足し合わせた数値を返します。

表計算はVizの作りを見た方が分かりやすいと思いますので、ここでViewをお見せします。

ここでPadding (bin)のMissing Valueが表示させることをお忘れなく。

参考のために、各Hex Latitude/Longitudeでのzip_codeでのMeasureと、各PolygonでのMeasure (Polygon)を比較表示します。

ところで、あるHex LatitudeとHex Longitude(とHexbin Sizingパラメータ)の組み合わせでは、そこに含まれるzip_codeが1つだけという場合があります。この場合は、今回のPaddingの式ではData Densificationができないため、Polygonを描写できません。

これを避けるのであればSelf-UNIONでのData Densificationをすればいいのですが、無理に地図を埋めることもないのかなぁと。

さて、これでPolygonによるHexbin Mapは完成です。これでMapをズームしてもスカスカすることはありません。

しかし、実は問題を一つ残しています。この状態では、実は六角形が歪んでいます。特に北側は縦に引き延ばされていますね。

これを解決するために、ひと手間加えます。


【Polygon Hexbin Mapを修正する】

Tableau上の地図はメルカトル図法による地図なので、その地図上へ緯度経度を投影させてPolygonを描写させるのであれば、緯度経度→xy平面への変換が必要です。

その変換については以下が参考になります。

https://hazm.at/mox/geo/mercator.html

というわけで、その変換をする計算フィールドを用意します。

ここでEarth Radius (km)は整数型パラメータで、6371が入っています。

Hexbin Size (km)も同様に整数型パラメータです。

Mercator Lat

[Earth Radius (km)] * LN(TAN(PI()/4 + (RADIANS([Latitude])/2)))

Mercator Long

[Earth Radius (km)] * RADIANS([Longitude])

HexLat Adjusted

HEXBINY([Mercator Long] / [Hexbin Size (km)],

[Mercator Lat] / [Hexbin Size (km)])

* [Hexbin Size (km)]

HexLong Adjusted

HEXBINX([Mercator Long] / [Hexbin Size (km)],

[Mercator Lat] / [Hexbin Size (km)])

* [Hexbin Size (km)]

ここで作成したHex Lat/Long Adjustedを用いて、Paddingの式も修正します。

Padding (Adjusted)

IF [zip_code] = { FIXED [HexLat Adjusted],[HexLong Adjusted] : MIN([zip_code])}

THEN 1 ELSE 6 END

Angleも使用するPaddingが変わるので、改めて作っておきましょう。

これ以降の表計算はすべてPadding (Adjusted) (bin)を使用するように設定してください。

Angle (Adjusted)

PI()/3 * INDEX()

Measure (Polygon) (Adjusted)

WINDOW_SUM(SUM([Measure]))

PolygonLat Adjusted

DEGREES(

2*ATAN(

EXP(

(

(WINDOW_AVG(AVG([HexLat Adjusted]))

+ SIN([Angle])*[Hexbin Size (km)]

)

/ [Earth Radius (km)]

)

)

)

- PI()/2

)

PolygonLong Adjusted

DEGREES(

(

WINDOW_AVG(AVG([HexLong Adjusted]))

+ COS([Angle])*[Hexbin Size (km)]

)

/ [Earth Radius (km)]

)

最後のPolygonLat/Lon Adjustedが仰々しくなったのは、xy平面→緯度経度への逆変換のためです。この式も参考URLに記載されています。

以下のように配置すれば、修正後のPolygon Hexbin Mapは完成です。

あとは適当にフォーマットを整えて配置すれば、目標のVizができます。

詳細はWorkbookをダウンロードしてください。


Polygonを用いたHexbin Map、いかがでしたか。

ご質問等はTwitterまたはLinkedinまでよろしくお願いします。