3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

StreamlitAdvent Calendar 2024

Day 2

【地図】Streamlit 1.39からst.pydeck_chartで選択した点を取得できるようになりました

Last updated at Posted at 2024-11-09

はじめに

10月にリリースされた Streamlit 1.39.0 から、st.pydeck_chart による地図描画で、選択した点を取得できるようになりました。

今回は、そちらの機能の紹介と、簡単なデモアプリを紹介しようと思います。

概要

st.pydeck_chart の紹介

st.pydeck_chart は、PyDeck ライブラリを Streamlit アプリ内で使用して、地図や3D可視化を簡単に表示できるコンポーネントです。

基本的には、次のようなソースコードで地図描画が可能になります。

import streamlit as st
import pydeck as pdk

# データを用意
data = [
    {"latitude": 35.6895, "longitude": 139.6917, "place": "東京"},
    {"latitude": 34.6937, "longitude": 135.5023, "place": "大阪"},
    {"latitude": 43.0642, "longitude": 141.3469, "place": "札幌"},
    {"latitude": 35.0116, "longitude": 135.7681, "place": "京都"},
    {"latitude": 33.5904, "longitude": 130.4017, "place": "福岡"},
]

# レイヤーを設定
layer = pdk.Layer(
    "ScatterplotLayer",
    data=data,
    get_position="[longitude, latitude]",
    get_color="[200, 30, 0, 160]",
    get_radius=50000,
)

# 初期表示の設定
view_state = pdk.ViewState(
    latitude=36.2048,
    longitude=138.2529,
    zoom=3,
)

# Pydeckチャートを表示
chart = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    map_style=None,
)

st.pydeck_chart(chart)

image.png

なぜ嬉しいか?

Streamlit 周りで有名なライブラリとして folium がありこちらなら柔軟性も高いです。

しかし、Streamlit 公式でこうした操作が行えるコンポーネントは存在しなかったので、「シンプルに実装したいんだけど、選択した点を取るにはサードパーティを入れないといけないな・・・」といったときに有用となります。

また、Snowflake に統合された Streamlit では地図描画として st.mapst.pydeck_chart しか使えず、両方とも選択した点の取得ができなかったので、それができるようになるのも嬉しいポイントですね。

ただし、記事公開時点では Streamlit in Snowflake の Streamlit バージョンの最新が 1.35 なので、1.39 の実装までもう少し待つ必要があります。

st.pydeck_chart で選択した点を取得する

st.pydeck_chart で選択した点を取得するには、下記のようにレイヤー設定時とコンポーネント呼び出し時にいくつか設定を追加してあげるだけで良いです。

import streamlit as st
import pydeck as pdk

# データを用意
data = [
    {"latitude": 35.6895, "longitude": 139.6917, "place": "東京"},
    {"latitude": 34.6937, "longitude": 135.5023, "place": "大阪"},
    {"latitude": 43.0642, "longitude": 141.3469, "place": "札幌"},
    {"latitude": 35.0116, "longitude": 135.7681, "place": "京都"},
    {"latitude": 33.5904, "longitude": 130.4017, "place": "福岡"},
]

# レイヤーを設定
layer = pdk.Layer(
    "ScatterplotLayer",
    data=data,
    get_position="[longitude, latitude]",
    get_color="[200, 30, 0, 160]",
    get_radius=50000,
+   pickable=True,
+   auto_highlight=True,
+   id="map",
)

# 初期表示の設定
view_state = pdk.ViewState(
    latitude=36.2048,
    longitude=138.2529,
    zoom=3,
)

# Pydeckチャートを表示
chart = pdk.Deck(
    layers=[layer],
    initial_view_state=view_state,
    map_style=None,
)

event = st.pydeck_chart(
    chart,
+   selection_mode="single-object",
+   on_select="rerun",
)

+event.selection

image.png

上記のアプリは次の Playground から操作できます。
st.pydeck_chart を実行するアプリ

パラメータ解説

  • pdk.Layer
    • pickable: その名の通り選択可能にするオプションです
    • auto_highlight: カーソルが当たっている部分にハイライトをするオプションです
    • id: Rerun時に地図描画を一意に固定するIDです(こちらの設定を忘れて、イベント情報更新されず困ったことがありました)
  • st.pydeck_chart
    • selection_mode: single-object と multi-object を指定でき、言葉の通り、一つを選択できるモードと複数を選択できるモードになります
    • on_select: ignore か rerun、コールバック関数を指定でき、選択時にアプリの再描画をするかしないかを指定できます(rerun かコールバック関数を指定した際は、先述の id パラメータを指定する必要があることに注意しましょう!)

おまけ:取得した選択点(辞書型)を Pandas データフレームに変換する

下記のコードを追加することで、辞書型で返却された選択点を Pandas データフレームに変換することができます。最後の "map" は、pdk.Layer の id パラメータに指定した値となります。

import pandas as pd

# オブジェクト部分を取得
objects = event["selection"]["objects"]["map"]
# pandas DataFrameに変換
df = pd.DataFrame(objects)

st.dataframe(df)

上記コードは、st.pydeck_chartselection_mode="multi-object" でもそのまま利用できます。

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?