Streamlit 1.36.0の新機能紹介

## Streamlitとは

StreamlitはPython向けのWebアプリケーションフレームワークです。  

https://streamlit.io/

Streamlitを使うとフロントエンドの知識ゼロでもデータを可視化するためのWebアプリケーションを簡単に作れます。以下のような機能が特徴。  
- 変数を地の文に書くだけで、GUIに出力される(**マジックコマンド**)
- `st.radio`や`st.text_input`のようなWidget APIを呼び出すだけで、GUIコンポーネントが生成される

## Streamlitの最新バージョン

Streamlitの最新バージョンは[Changelog](https://docs.streamlit.io/library/changelog)で確認できます。  
2024/6/22時点で最新バージョンは1.36.0です。  

https://docs.streamlit.io/library/changelog

1.36.0では次がHighlightsおよびNotable Changesとしてアナウンスされています。  

- st.navigationによる動的なページナビゲーション
- 横棒グラフ
- st.expanderのラベルにアイコンを表示
- st.columnsで並べる要素の縦方向のアラインメントを設定
- カスタムコンポーネントがコールバック関数に対応
- グラフの軸ラベルのカスタマイズ
- protobuf 5.x.xに対応

小ネタが色々という感じですね。


## st.navigationによる動的なページナビゲーション

マルチページアプリV2と呼ばれている機能強化の一環で実装されました。  
これまでは```pages```ディレクトリの配下にPythonファイルを置いておくとそれが自動的にサブページになるという仕組みだったのですが、```st.navigation```と```st.Page```を用いてプログラマブルにサブページを定義できるようになりました。  
```st.Page```にはPythonファイルのパスを指定します。```pages```ディレクトリの配下になくてもOKでした！  

```py:navigation.py
import streamlit as st

pg = st.navigation([st.Page("page_1.py"), st.Page("page_2.py")])
pg.run()
```

https://docs.streamlit.io/develop/concepts/multipage-apps/page-and-navigation

## 横棒グラフ

```st.bar_chart```に```horizontal=True```オプションを指定することで棒グラフを横棒グラフにできるようになりました。  

![Horizon bar chart](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/657c3074-c0f1-d8f2-8213-d32399dce5dc.png)

https://docs.streamlit.io/develop/api-reference/charts/st.bar_chart

## st.expanderのラベルにアイコンを表示

```st.expander```に```icon```パラメータを指定することでラベルにアイコンが表示されるようになりました。  
Googleマテリアルアイコンにも対応しています。以下の例では```icon=":material/casino:"```を指定してみました。  

![Expander icon](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/067d6eaf-b668-5488-c080-9de0b0bc3de8.png)

## st.columnsで並べる要素の縦方向のアラインメントを設定

https://x.com/AkSakatoku/status/1804484802261012659

## カスタムコンポーネントがコールバック関数に対応

カスタムコンポーネントが```on_change```のようなコールバック関数を実装できるようになりました。  
これまでもハックすれば実装できたということですが、1.36.0から正式対応したようです。  

例えばStreamlitでWebカメラなどを扱える[streamlit-webrtc](https://github.com/whitphx/streamlit-webrtc)の場合、コンポーネント内部のステートが変化したときに```on_change```を呼び出してくれます。  
以下のサンプルではステートが変化したときにログを残すだけですが、アイディア次第で色々なことができそうです。  

```py:custom_component_on_change.py
import streamlit as st
from streamlit_webrtc import webrtc_streamer

def on_change():
    # ソースコード省略。ctx.stateを文字列に変換している
    st.session_state.log += f"[{dt}] {state}"

st.title("WebRTC demo")
st.session_state.ctx = webrtc_streamer(key="sample", on_change=on_change)

log = ""
if "log" in st.session_state:
    log = st.session_state.log
st.text_area("Log", log, height=200)
```

https://x.com/AkSakatoku/status/1804905272839966992

今後は自分のアプリと高機能なカスタムコンポーネントをより密に連動させることができそうです！  

## グラフの軸ラベルのカスタマイズ

グラフに軸ラベルが設定できるようになりました。  
対象のグラフは```st.area_chart```、```st.bar_chart```、```st.line_chart```および```st.scatter_chart```の4つです。いずれもStreamlitに組み込まれているグラフ描画関数です。  
```x_label="X軸のラベル", y_label="Y軸のラベル"```のようにオプションを指定します。  

![Axis label](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/a0f979c8-c7dc-7939-f50b-5e1ec0bfade2.png)

## protobuf 5.x.xに対応

protobuf(Protocol Buffers)は通信でやりとりするデータをシリアライゼーションする技術です。  
Streamlitはブラウザ上で動作しているフロントエンドとサーバ上で動作しているバックエンドの間の通信をWebSocketとprotobufで行っているようです。  

protobufは完全に枯れた技術ではないため、ライブラリのアップデートがしばしばあります。2024年6月23日時点ではPythonライブラリの最新版が5.27.1でした。  

https://pypi.org/project/protobuf/

一方、Streamlitが依存しているバージョンを確認すると、1.35.0までは3.20以上かつ5未満でしたが、1.36.0では3.20以上かつ6未満になっていました。これでよりも依存関係を解決しやすくなっていますね。