Tableauの拡張機能のTabPyって?

Tableauの拡張機能の一つでPythonをTableauの計算式で走らせることができるようになります。
接続しているデータベース内の値を使って予測をviz上で行ったり、LOD式を駆使してもできなかった計算などを行うことができます。
今回ブログでご紹介するように、外部APIから情報を取ってきて直接可視化することも可能です。

Tableauの理解度はそこそこ(Certified Associate)、Pythonど素人でも実装ができました。
新しいVizや分析のヒントになれば幸いです。

TabPyを使ってみよう

まずはインストールと設定

インストールの方法はこちらのGithubにあります。私はpip installができないくらいの初心者だったので躓いた点も書いておこうと思います。

  1. Anacondaをインストールする
  2. TabPyをインストールする リンクはこちら
  3. Anaconda Powershellを起動する。tabpyを入力してEnter→tabpyが起動した状態になる
  4. Tableau Desktopを起動する
  5. Tableau Desktopで拡張機能の設定を有効にする 手順はこちら
  6. SCRIPT_関数がTableauで使えるようになる

TabPyを設定すると使えるようになる関数

以下の4つの関数が使えるようになります。今回はPythonを追加しましたが、Rを追加しても同じ関数が使用できます。ただし記述の方法がことなります。Tableauの関数一覧にも載ってました。

  • SCRIPT_BOOL
    • True または Falseで返す
  • SCRIPT_INT
    • 整数を返す
  • SCRIPT_REAL
    • 実数を返す
  • SCRIPT_STR
    • 文字列を返す

特に接続したデータベース内の情報を変数として使わなくても、単独でも使用可能です。
TabPyの無駄遣いですが、例えばSCRIPT_STRで必ず"CAT"を返す、のようなこともできます。

APIで情報を取得してみよう

せっかくTableauなのでいい感じにビジュアライズして変化がわかりやすいものを作ってみようと思いました。
今回は世界の気象情報を無料APIで提供しているOpenWeatherのAPIを使って世界の大気汚染具合を見てみたいと思います。

無料APIの中でAir Pollution APIをTableauから呼び出してみようと思います。入力で必須なのは緯度、経度、APIキー(ご自身のを作成してください)の3つでした。
どんなJSONで返ってくるのかjupyter notebookで確認します。

import requests
url = 'http://api.openweathermap.org/data/2.5/air_pollution?lat={}&lon={}&appid={your key}'\
.format('48.856614', '2.352222')

result = requests.get(url).json()
{'coord': {'lon': 2.3522, 'lat': 48.8566}, 'list': [{'main': {'aqi': 1}, 'components': {'co': 233.65, 'no': 0.19, 'no2': 12.34, 'o3': 15.38, 'so2': 0.9, 'pm2_5': 8.04, 'pm10': 9.56, 'nh3': 0.91}, 'dt': 1622260800}]}

世界各地の数値を取得したいので緯度経度情報が必要になります。
こちらからcsvをダウンロードしました。

Tableauで関数を作成

準備

  1. 緯度経度を地理情報を含まない数値のメジャーに複製する
    Tableauでは自動的に地理情報を含んでいると判定されるので、可視化用にオリジナルは取っておきます。
    数値として扱いたいので、それぞれコピーして地理情報を含まない数値のメジャーとします。
  2. パラメータを作成
    大気汚染の各指標を切り替えて表示したいのでパラメータを作成します。
    JSONの返り値を参考に用意しました。
  3. 途中式を作成
    パラメータでの切替のために1つ式を挟みました。文字列にするだけの簡単なものです。
    これはいろいろと下記メイン関数で試行錯誤した結果たどり着いたものですが、先にやっておけばよかったことの部類に入るので準備に記載します。
 # request_base
SCRIPT_str("
result = _arg1[0]
return result
",
[type of pollutant])
  1. 首都に絞るフィルターをかける
    都市ごとにしてしまうと国の塗りつぶしが上手くいかなったので今回はIscapital=1でフィルターしています。

いざSCRIPT_REAL

# request
SCRIPT_real("
import requests

url = 'http://api.openweathermap.org/data/2.5/air_pollution?lat={}&lon={}&appid={yourkey}'\
.format(_arg1[0], _arg2[0])

type = _arg3[0]

result = requests.get(url).json()['list'][0]['components'][type]
return result
",
attr([Lat (non-geo)]), attr([Lon (non-geo)]), ([request_base]))

TabPyでは_arg数字という方法で変数を書きます。そして最後に数字の順番に並べます。
以下詳細です。

  1. まず返り値が何かを関数名で指定する(今回は実数とわかっているのでSCRIPT_REALに指定)
  2. requestsをimportする
  3. APIのリクエスト先を記載(.formatでtableauに接続したcsvから緯度と経度を入力するように設定)
  4. typeはパラメータで指定する(準備で作成した関数を指定)
  5. return に直接resultの内容を記載するとエラーになる(returnの内容に関数の正式な返り値が来ないとダメらしい)のでresultというクッションを置く
  6. SCRIPT_関数はLODのように集計された値か一意の値でないと受け付けないため_arg数字の箇所にattrなどを追加

可視化した結果!


右のパラメータで切り替えると違う指標も見られます!

ただし…切替に30秒ほどかかることが…
それは各地点毎にAPIリクエストを飛ばしていて、その都度import requestsなどSCRIPT_REALに書いてある内容をすべて実行しているから…
※Tableau Serverにパブリッシュして動かす場合はServer側にもPython Extensionを追加する必要があります

まとめ

手元のデータに加えて外部データをタイムリーに取得できる機能はダッシュボードをより充実させます!
ぜひお試しあれ!
今回はAPI接続をしましたが、手元のデータ加工や予測などにも使用できます。
英語でも日本語でもTabPyに関する情報が少なかったのでいろんな人の手を借りて実装しました。
元々は指標切替に5分半かかるダメダメなtwbだったところを30秒に短縮した経緯があるので、また別の機会にブログにしようと思います。