導入
Streamlitって便利ですよね。
基本的なwidgetを利用するだけで、必要要件を満たしたアプリに仕上げることができ、個人利用で重宝しています。
初めての方はこちらのページを参照すると、streamlitで何ができるかわかると思います。
色々触っていく中で、躓いたポイントがありました。
...これ、階層構造の制御が上手く出来なくないか?
時系列データを扱う際には特に問題なかったのですが、階層構造のデータを扱う場面でん?ってなりまして。
何かいい方法がないかなと探していたところ、便利なカスタムコンポーネントがありましたので、共有します。
紹介
➀streamlit_tree_select
〈Github〉
求めていたものだ!! ってなりました。
簡単に言えば
- Folder Cの子に➀Sub-folder D ②Sub-folder E ③Sub-folder Fの3種が存在
- 上記②Sub-folder Eの子に、④Sub-sub-folder A ⑤Sub-sub-folder Bの2種が存在
- これらを纏めて表示することが可能である
といったところでしょうか。
階層構造のデータを扱うだけなら、これだけで十分だと思います。
②StreamlitAntdComponents
streamlit_tree_selectだけでも十分に魅力的なのですが、実際に利用するとやや気になる点があります。
個人的には下記が気になりました。
- どの階層が子を持つかがやや分かりにくい (>で表示されてはいますが...)
- UIが簡素で少しダサい
※あくまで個人的な意見なので、別に気にならないよって人は飛ばしてもらって結構です。
どうにか改善できないものかと色々探していたところ、見つかったのがStreamlitAntdComponentsでした。
〈Github〉
CopilotとGithubから得られる情報だけでも、多岐にわたり利用できるコンポーネントだと分かります。
今回はスルーしてしまいますが、checkboxのグループとか便利そうですね...
本題に戻り、treeで何ができるのかを調査してみようと思います。
実用例
➀利用までの流れ
はじめに、ライブラリのインストールを行いましょう。
pip install streamlit-antd-components
続けて、ライブラリをimportします。
import streamlit as st
import streamlit_antd_components as sac
②パラメータ理解
一つ一つ説明したかったのですが、パラメータ20個もあったので直貼りしてしまいます。
Chat GPT4oから帰ってきた和訳回答がこちらです。
- items: ツリーのデータ
- index: デフォルトで選択されるツリー項目のインデックス
- format_func: ラベルフォーマット関数。文字列を受け取り、文字列を返します
- label: ツリーのラベル。文字列およびマークダウン形式の文字列に対応
- description: ツリーの説明。文字列およびマークダウン形式の文字列に対応
- icon: ツリー項目のアイコン
- align: ツリーの配置
- size: ツリーのサイズ。Mantineサイズおよびピクセル単位の整数に対応
- color: ツリーの色。デフォルトはStreamlitのプライマリカラー。Mantineカラー、16進数、およびRGBカラーに対応
- width: ツリーの幅
- height: ツリーの高さ
- open_index: デフォルトで開かれるインデックス。指定がない場合、ツリーはデフォルトインデックスの親ノードを開きます
- open_all: すべての項目を開くかどうか。優先順位は[open_all > open_index]
- checkbox: 複数選択を許可するチェックボックスを表示するかどうか
- checkbox_strict: 親項目と子項目が関連付けられないかどうか
- show_line: 線を表示するかどうか
- return_index: Trueの場合、ツリー項目のインデックスを返します。デフォルトはラベルを返します
- on_change: 項目が変更されたときのコールバック関数
- args: コールバック関数への引数
- kwargs: コールバック関数へのキーワード引数
- key: コンポーネントの一意の識別子
on_changeやargs、key等は他のwidgetでも設定されているパラメータなので、何となく意味合いが分かりますね。他の項目は基本的にwidgetの装飾といったところでしょうか。
気になったパラメータについて、③サンプル例で実践してみようと思います。
③サンプル例
# サンプルデータ
category_dict = {
"文系科目": ["英語", "国語", "社会"],
"理系科目": ["数学", "理科"],
}
# ツリー構造のウィジェット
with st.container():
selected_category = sac.tree(
items=[
sac.TreeItem(
category,
children=[
sac.TreeItem(sub_category, disabled=False)
for sub_category in sub_category_list
],
disabled=False
)
for category, sub_category_list in category_dict.items()
],
label="科目を選択してください",
description="文系科目と理系科目を選択することができます。複数選択が可能です",
format_func="title",
icon="bell", # Ant Design(AntD)のアイコンセットから
width=500,
height=1500,
open_all=True,
checkbox=True,
show_line=True,
key="sample",
)
実際に書いてみたものがこちらになります。
sac.treeのitemsにsac.TreeItemを利用することで、図表のような親ノード子ノード表示が可能です。
複数選択のウィジェットはmultiselectが主流ではありますが、項目数が多くなるとなかなか使いにくいですよね。そういう時にsacはかなり強力だと思います。