StreamlitでPyGWalkerを試してみる
はじめに
前から存在は知っていたものの、なんか難しそうなので手を出してなかったPyGWalkerを試してみました。
ここにPyGWalkerの紹介と、デモコードがあるので、これを動かしてみます。
例によって、以前作ったStreamlitのテンプレートを使用します。
依存関係のインストール
pandas, streamlit, pygwalkerをインストールするように書かれていますが、pandasはstreamlitに含まれているので、pygwalkerだけrequirements.txtに追加してインストールします。
streamlit
+ pygwalker
pip install -r requirements.txt
エラーの発生
インストール中にエラーが発生しました。
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for duckdb
Running setup.py clean for duckdb
Failed to build duckdb
ERROR: Could not build wheels for duckdb, which is required to install pyproject.toml-based projects
duckdbがインストールできないと言われています。
調べてみるとPython 3.12にはまだ対応してなさそうです。
Dockerfileを修正して、3.11.7を指定して開発コンテナをリビルドします。
- FROM python:latest as base
+ FROM python:3.11.7 as base
これでエラーが解消されました。
今回インストールしたパッケージのバージョンは以下の通りです。
Package Version
------------------ -------
streamlit 1.31.1
pygwalker 0.4.6
環境が整ったので、次にデモコードを実行してみます。
デモコードの実行
コードが2種類書かれていますが、PyGWalkerのバージョンが0.3.9以降は下のコードを使用する方がパフォーマンスが良いとのことなので、そちらのコードを使用します。
StreamlitでのPyGWalkerの新しいAPI(推奨)
こちらを起動すると、PyGWalkerの画面が表示されました。
参考ドキュメントはここから「PyGWalkerチャートの状態の保存」に話が移ってしまい、どうやって使うのかがよくわからないので、1つずつ触ってみたいと思います。
動作確認
「Data」タブ
起動時は「Visualization」タブが選択されています。
「Data」に切り替えると、読み込んでいるデータが表示されます。
データは先ほどコピペしたコードに書かれているhttps://kanaries-app.s3.ap-northeast-1.amazonaws.com/public-datasets/bike_sharing_dc.csv
の中身かと思われます。
読み込んだデータが100件ずつ表示されています。
ヘッダーの下には、そのカラム内のデータの大まかな分布が、グラフや数値で表示されています。
データ自体は編集できないようですが、ヘッダーのところは2か所触れるようです。
フィルタ
カラム名の横にあるフィルタをクリックすると、そのカラムのデータをフィルタリングできます。
フィルタの解除は「Filters」のところにあるカラム名を「×」ボタンで消せばOKです。
尺度の変更
カラム名の左にあるアイコンを押すと、以下のメニューが表示されます。
nominal(名義尺度)、ordinal(順序尺度)、quantitative(量的尺度)、temporal(時間尺度)の4つの尺度が選べるようです。
それぞれがどういう意味か調べてもドキュメントにたどり着けなかったので、ざっくりCopilotさんに聞いてみると、以下のような回答をもらいました。
- Nominal (名義尺度):
- 名義尺度は、カテゴリやグループを表すデータを指します。
- 例えば、色(赤、青、緑)や都市名(東京、ニューヨーク、パリ)などが該します。
- 順序や大小の意味はありません。
- Ordinal (順序尺度):
- 順序尺度は、順序を持つデータを表します。
- カテゴリ間の相対的な順序が重要ですが、具体的な数値はありません。
- 例えば、評価(低い、中程度、高い)や学年(1年生、2年生、3年生)などが該当します。
- Quantitative (量的尺度):
- 量的尺度は、数値データを表します。
- これには連続的な数値(身長、体重、温度など)と離散的な数値(人口、購入数、評価点など)が含まれます。
- 量的尺度は算術演算が可能です。
- Temporal (時間尺度):
- 時間尺度は、日付や時刻を表すデータです。
- 例えば、日付(2024年2月7日)や時刻(午後3時30分)が該当します。
鵜呑みにしていいかはわかりませんが、なんとなく意味はつかめました。
おそらくこの尺度を変更することで、集計やグラフの表示が変わってくるのだと思われます。
(quantitativeの場合は合計や平均がだせるとか)
「Data」タブのまとめ
「Data」タブは、読み込んだデータの中身を確認したり、尺度の変更やフィルタリングができることがわかりました。
ここで設定したフィルタが、後の「Visualization」タブのグラフに反映されるかは確認が必要そうです。
「Visualization」タブ
続いて「Visualization」タブを見てみます。
まず目につくのは左側にある「Field List」です。
ここに先ほど見たデータのカラム名が表示されています。
ただ何らかの基準でセパレータで上下に分けられ、データにはなかったものもいくつか表示されています。
- 上側
- Measure names
- 下側
- Row count
- Measure values
また、各カラム名の横にはアイコンが表示されており、これは先ほどの「Data」タブで設定した尺度を示しているものと思われます。
ただ、ここで気付いたのですが、「Data」タブで設定した尺度は、こちらには反映されていないようです。
先ほど「Data」タブで、dateカラムをtemporalに変更してみましたが、こちらを見るとnominalに戻ってしまっています。
「Data」タブで保存ボタンが有ったり、「Visualization」タブでデータを読み込みなおすみたいなボタンがあるのかと思ったのですが、いくら探しても見つかりませんでした。
以上のことから、「Data」タブと「Visualization」タブはそれぞれ独立していると思われます。
(もし勘違いしているようでしたら、コメント等で教えていただけると助かります)
Field List & グラフエリア
「Field List」の中から、いくつかのカラムを選択して、グラフを書いてみます。
サンプルデータは1時間ごとの気温、湿度、風速のデータのようなので、「X-Axis」に「month」、「Y-Axis」に「temperature」を持って行ってみます。
すると月ごとの気温の合計(sum)が表示されました。
合計は何の意味もないので、平均が見たいです。
Y-Axisの「temperature」の横にある「sum」をクリックすると、以下のメニューが表示されます。
ここで「Mean」を選択すると、平均が表示されました。
「Mean」以外にも「Min」や「Max」で、最低気温最高気温簡単に描画できました。
X-AxisとY-Axisを入れ替えても問題なく描画できました。
さらにX-Axisに「year」を追加すると、年ごとにグラフが分かれて表示されました。
さらに「am or pm」を追加してみると、以下のように「month」がなくなってしまいました。
どうやら追加できるのは2つまでのようです。
「hour」を追加して時間ごとの平均気温を出したかったのですが、「hour」はセパレータの下にあり、追加してみると以下のようになりました。
これはおそらく「hour」がquantitative(量的尺度)になっているためだと思われます。
「hour」は上で書いた内容的に、ordinal(順序尺度)になっているべきなので、これを変更してみます。
変更は「Field List」のカラム名横のアイコンから行えました。
ただ、ここを変更しただけではうまくいかず、上の画像の「Move to dimensions」をクリックして、セパレータの上側に移動させる必要がありました。
ここまでやると、月ごとの時間帯別の平均気温が表示されました。
逆にセパレータの上から下に移動させるには「Move to measures」をクリックすればOKです。
どうやら、セパレータの上側にあるものは「dimensions」、下側にあるものは「measures」と呼ばれるようです。
これらの移動はドラッグ&ドロップでもできるようです。
また、「measures」に関しては、複数個同時に描画することができるようです。
追加されたカラムについて
上でも書きましたが、読み込んだデータに対して、以下のカラムが追加されています。
- dimensions
- Measure names
- measures
- Row count
- Measure values
このうち「Row count」だけは意味が分かったのですが、他のカラムについてはどうやって使うのか全く分かりませんでした。
「Row count」は、データの行数を表しているので、データの数をグラフにしたい場合に、これを使えば良いようです。
Filters
「Filters」のところにField Listからカラムをドラッグ&ドロップすると、そのカラムの値でフィルタリングできるようです。
ドラッグ&ドロップすると設定画面が表示されるので、ここでフィルタする値を設定できます。
設定を完了するとグラフに反映され、Filtersのところにはフィルタしているカラム名と、除外している値が表示されています。
Color & Opacity & Size & Shape & Details
これらはグラフの中の要素を、任意のカラムの値によって色や透明度、サイズ、形等を変更することができるようです。
Color
Opacity
Size
Shape
Details
わかりづらいですが、Shape
は線が入っています。
Details
はShape
と何が変わっているのかわかりませんでした。。。
各要素は1つずつしか設定できないようです。
(Color
にseasonとyearを設定するとかはできない)
使いどころがあるかわかりませんが、1個ずつなら複数要素同時に設定することはできるようです。
メニューバー
続いてメニューバーにある各アイコンを見て行きます。
undo & redo
おなじみの「戻る」と「進む」です。
Aggregation & Painter
「Aggregation」は通常がONの状態で、OFFにするとグラフの集計が解除されて、各データの値が表示されるようになります。
この状態で「Open Painter」を選択すると、一部のデータに色を付けたり、データを削ったりできるようです。
これは「Aggregation」をONに戻しても残っています。
具体的な使い道は思いつきませんでしたが、何かの役に立つかもしれません。
(グラフの強調したい部分に色付けするとか?)
Mark type
グラフの種類を変更できるようです。
かなり多くの種類が用意されているようです。
Stack
グラフの積み上げを切り替えできます。
- None: 積み上げなし
- Stack: 積み上げ
- Normalize: 積み上げを正規化
- Center: 積み上げを中央揃え
Transpose
X-AxisとY-Axisを入れ替えることができます。
Sort
グラフの「dimensions」が「measures」の値でソートできるようです。
昇順と降順それぞれ選べます。
ただ、解除方法がなさそうだったので、解除したい場合は一度カラムを外して、再度追加する必要がありそうです。
Add Computed Field
新しい集計カラムを追加できるようです。
SQLで指定できるようなので、複雑な集計も可能そうですが、使いこなすのは難しそうです。
こちらにドキュメントがあるようです。
Axes Resizing
ONにすると、グラフのZoomができるようになります。
マウスのホイールでズームできるようです。
Layout Mode
グラフのレイアウトを3種類から変更できます。
Fixed
Auto
Container
ぱっと見は「Auto」よりも「Container」の方が使い勝手が良さそうです。
Coordinate System
GenericとGeographicの2種類から選べるようです。
位置情報を持つデータを描画する際には、Geographicを選ぶと良さそうです。
debugging
ON/OFFできるのですが、何が変わっているのかはわかりませんでした。。。
Export
png, svg, base64の3種類から形式を選択し、作成したグラフをエクスポートできるようです。
base64はクリックしても何も起こっていないように見えましたが、クリップボードにコピーされていました。
Export as csv
グラフのデータをcsv形式でエクスポートできます。
元のデータが出てくるのではなく、集計された(グラフを形作る)データになります。
Config
Primary ColorやScale等、グラフの設定を変更できるウィンドウが表示されます。
export_code
作成したグラフはリロード等で消えてしまうのですが、ここで生成されたコードを使って、再度同じグラフを描画できるようです。
コードの使い方はこちらに書かれていますが、どうやら古いバージョンのコードのようです。
新しいコードの方では、StreamlitRendererのSpec
の引数に渡せば良いようです。
@st.cache_resource
def get_pyg_renderer() -> "StreamlitRenderer":
df = pd.read_csv(
"https://kanaries-app.s3.ap-northeast-1.amazonaws.com/public-datasets/bike_sharing_dc.csv"
)
# アプリをパブリックに公開する場合、他のユーザーがチャートの設定ファイルに書き込めないように、デバッグパラメータをFalseに設定する必要があります。
< return StreamlitRenderer(df, spec="./gw_config.json", debug=False)
> return StreamlitRenderer(df, spec=vis_spec, debug=False)
Limit
グラフの表示件数を制限できるようです。
ただ、どういう順番で制限されるのかはわかりませんでした。
Chartタブ
メニューバーの上にある「Chart 1」の横の「+ New」をクリックすると、新しいグラフを描画できるようです。
また、既存のグラフの右側のアイコンをクリックするとメニューが表示され、グラフの名前の変更や削除、コピーができるようです。
新しいChartでは、Field Listの設定情報がリセットされてしまうので、基本的にはコピー作成を使った方が良さそうです。
また、「export_code」には、全てのグラフの情報が含まれるようです。
Mode
今までは「Walker」のモードでしたが、Rendererというモードもあります。
Rendererは、Walkerで作成したグラフを表示するだけのモードのようです。
まとめ
PyGWalkerの機能をざっくり触ってみました。
Tableauのようなツールと聞いていましたが、Tableauを使ったことがないのでいまいちピンと来てなかったのですが、Excelのピボットグラフのような感じということがわかりました。
export_codeを使えば作成したグラフを再利用できるので、複数人で共有する場合には便利そうです。
このあたりの機能を使ってできそうなアイディアを思いついたので、そのうち実装してみたいと思います。 → 作りました
Discussion