今回もStreamlitの記事です。まだ続く予定です。
今回はStreamlitのコンテナやプレースホルダーの紹介です。Streamlitでは基本的にコードで実行された順番に上から下へと要素が順次描写されていきます。
しかし、場合によっては描写済みのところに遡って要素を追加したり、一度描写した要素を再度書き直したりしたいという場面もあります。
一応、何かしらウィジェットを操作すれば画面全体が全部再描写されるので、前回の記事で紹介したst.session_stateをフル活用すれば大抵のことはできてしまうのですが、この記事で紹介するコンテナを有効に使えばより手軽で柔軟に実装できます。
空要素をプレースホルダーとして挿入するst.empty()
最初の方法は、単一の要素を格納できるプレースホルダーを挿入するst.empty()です。
ドキュメントはこちら。
これは場所を一つ予約しておいて、後からその中身を書き換えることができます。これの次に複数要素を格納できるコンテナってのを紹介しますが、それと違って単一要素しか入れられないので何か書き込むと値が上書きされて書き変わっていきます。
通常、Streamlitで何か書き換えたかったらページ全体が再描写されるので、単一要素を書き換えられるのは良いですね。使い方としてはwith文で使う方法と、変数に格納しておく方法があります。ドキュメントで、時間によるカウントアップの例が取り上げられているのでやって見ましょう。普通にfor文でst.write()したら毎行追記されてしまいますが、プレースホルダーを用意しているのでその中身が順次書き換えられていく動きが実装できます。
with文で使う場合はこうなります。
import streamlit as st
import time
with st.empty():
for seconds in range(60):
st.write(f"{seconds}秒経過 ")
time.sleep(1)
st.write("一分経過")
変数に格納する場合はこうです。
import streamlit as st
import time
placeholder = st.empty()
for seconds in range(60):
placeholder.write(f"{seconds}秒経過 ")
time.sleep(1)
placeholder.write("1分経過")
withだと宣言した直後にそこを書き換えるような使い方しかできませんが、変数を用意せずにすみコードがシンプルになります。
一方で変数に格納しておくと、上記のサンプルコードでは直後に書き換えているのであまりメリット感じませんが実際は、何か別の処理を色々やってから改めて確保していた場所を書き換えるといったことができます。
複数の要素を格納できるコンテナを作るst.container()
次に紹介するのが、st.container()です。ドキュメントはこちら。
これもempty()同様にほぼプレースホルダーなのですが、違うのは複数の要素を格納できることです。その代わり、上書き修正ができません。
後からこのコンテナの中に要素を追加していくことができます。コンテナの中では追加されたものが上から順番に表示されます。
超シンプルな例ですが、以下のようなのをやって見ましょう。
import streamlit as st
st.write("1行目")
container = st.container()
st.write("2行目")
container.write("3行目")
container.write("4行目")
全部st.writeで実装したら、1行目から4行目までが順番に表示されるところですが、コンテナを1行目と2行目の間に置いているので、これを実行すると3行目と4行目は1行目と2行目の間に出力されます。