streamlit入門 データ可視化

Streamlit入門 - レイアウトの設定

これまでテキストやグラフ、ドロップダウンなどのインプットを個別で表示する方法を見てきました。

(過去記事はこちら)

今回は、より本格的なダッシュボードやWebアプリを作るための少し進んだレイアウト機能を見ていきたいと思います。

これらを使いこなせると、実は簡単なのにもかかわらず「おおっ」というようなダッシュボードやWebアプリが作成できます

では早速見ていきましょう。

レイアウト設定

以下の5つのレイアウト設定方法を見てきます。

  • サイドバー
  • 列の設定
  • エクスパンダ―
  • コンテナ
  • 空のコンテナ

サイドバーの設定

まずはよく利用させるサイドバーの使い方です。

Streamlitでは非常に簡単に実現することができますが、やり方が以下の2種類あります。

  1. st.sidebar.メソッドで指定する。
  2. With st.sidebar: で指定する

では、まず1のst.sidebar.メソッドで指定する方法を見ていきましょう。

例えば、ドロップダウンをサイドバーに持ってきたいときは、

st.sidebar.selectbox(...)

とします。

実際の例を見てみましょう。

ここでは、ドロップダウン・リストと日付のインプットをサイドバーに持ってきて、メインにグラフを表示します。

stocks = st.sidebar.multiselect(
    label='銘柄を選んでください',
    options=['スノーピーク', '楽天', 'トヨタ'],
    default='スノーピーク',
)

dates = st.sidebar.date_input(
    label='期間',
    min_value=datetime.date(2021, 1, 4),
    max_value=datetime.date(2021, 12, 31),
    value=[datetime.date(2021, 1, 4), datetime.date(2021, 12, 31)]
)

st.header(f'{"と".join(stocks)}が選択されています。')
if len(dates) == 2:
    start_date = dates[0]
    end_date = dates[1]
    # st.subheader(f'期間は{start_date.strftime("%Y年%m月%d日")}から{end_date.strftime("%Y年%m月%d日")}までです。')
    str_start_date = start_date.strftime('%Y-%m-%d')
    str_end_date = end_date.strftime('%Y-%m-%d')
    st.subheader(f'{start_date.strftime("%Y年%m月%d日")}から{end_date.strftime("%Y年%m月%d日")}までの株価推移')
    print(str_start_date)
    st.line_chart(df.loc[str_start_date: str_end_date][stocks])

すると以下のように左側にサイドバーが表示され、サイドバーを閉じることも可能です。

上記の書き方でもいいのですが、個人的にはわかりやすいwith句を使った2のやり方を使っています。

with句を使うときは、with st.sidebar: の中に、今まで通りのウィジェット等を書くだけです。

with st.sidebar:
    stocks = st.multiselect(
        label='銘柄を選んでください',
        options=['スノーピーク', '楽天', 'トヨタ'],
        default="スノーピーク",
    )

    dates = st.date_input(
        label='期間',
        min_value=datetime.date(2021, 1, 4),
        max_value=datetime.date(2021, 12, 31),
        value=[datetime.date(2021, 1, 4), datetime.date(2021, 12, 31)]
    )

特に複数の項目を設定する場合はこちらの方が見やすいですね。

列の設定: st.columns

今までは1行に1列だけ要素を設定しましたが、1行に複数列を横に並べることが簡単にできます。

それにはst.columns()を使いますが、2通りの引数の設定方法があります。

  • 整数を渡す
    引数で渡された数分の等間隔の列を作成します。
    eg. st.columns(2)とすると幅が同じ2列が作成されます。
  • 整数のリストを渡す
    引数の要素分の列が作成され、要素はそれぞれの幅を表します。
    eg. st.columns([3, 2, 1])とすると、3列作成され、3列目は1列目の3倍の幅、2列目は3列目の2倍の幅になります。

戻り値は列のリストで返ってきます。

では、実際に見てみましょう。

st.columns(2)で2列を作成し、col[0]が1列目、col[1]が2列目を表します。

あとは、それぞれに対して、今まで学んだようなメソッドを呼び出すだけです。

col = st.columns(2)
stocks = col[0].multiselect(label="銘柄を選んでください",
                options=df.columns,
                )
 
dates = col[1].date_input(
    label='期間を選んでください',
    min_value=datetime.date(2021, 1, 4),
    max_value=datetime.date(2021, 12, 31),
    value=[datetime.date(2021, 1, 4), datetime.date(2021, 12, 31)]
)

if st.button('表示'):
    st.header(f'{"と".join(stocks)}が選択されています。')
    if len(dates) == 2:
        start_date = dates[0]
        end_date = dates[1]
        str_start_date = start_date.strftime('%Y-%m-%d')
        str_end_date = end_date.strftime('%Y-%m-%d')
        st.subheader(f'{start_date.strftime("%Y年%m月%d日")}から{end_date.strftime("%Y年%m月%d日")}までの株価推移')
        print(str_start_date)
        st.line_chart(df.loc[str_start_date: str_end_date][stocks])        

幅を設定したい場合は以下のようにリストで渡します。

col = st.columns([7, 3])

この場合、以下のように要素数である2列作成され、幅の比が7対3で分割されます。

エクスパンダー: st.expander

エクスパンダ―は言葉で説明するのはなかなか難しいので、実際に見ていただいた方が早いと思いますが、デフォルトは非表示ですが+ボタンを押すことによって開くものです。

使い方は簡単で、expanderに入れる部品をwith st.expander("label"):のwith句の中に入れます。

引数部分はexpanderに表示されるテキストになります。

st.header('2021年の株価推移')
st.line_chart(df[['スノーピーク', 'ANA', 'トヨタ']])
with st.expander("解説を見る"):
     st.subheader("2021年の比較")
     st.write("2021年8月以降はコロナの影響でキャンプの需要が高まり、スノーピークの株価が大幅に上昇した。")
     st.subheader("今後の見通し")
     st.write("ワクチン接種などにより、自動車需要の回復や飲食店、旅行業などの回復も見込まれる。")

expander部分の株価に関するコメントは適当です。

コンテナ: st.container

例えば、以下のようなレイアウトを組みたいような場合はよくありますね。

この場合は左側の2行を一つのコンテナでまとめてやることで実現することが可能です。

1画面を2列に分けて、1列目に2行の要素を設定します。

具体的な例は以下のような感じで、2行目からが左の列で2つのインプットを設定し、21行目からが右の列になります。

cols = st.columns([3, 7])
with cols[0].container(): # 左の列にコンテナを設定
     stocks = st.multiselect(
          label='銘柄を選んでください',
          options=['スノーピーク', '楽天', 'トヨタ'],
          default="スノーピーク",
     )

     dates = st.date_input(
          label='期間',
          min_value=datetime.date(2021, 1, 4),
          max_value=datetime.date(2021, 12, 31),
          value=[datetime.date(2021, 1, 4), datetime.date(2021, 12, 31)]
     )

if len(dates) == 2: 
    start_date = dates[0]
    end_date = dates[1]
    str_start_date = start_date.strftime('%Y-%m-%d')
    str_end_date = end_date.strftime('%Y-%m-%d')
    # 右の列にはグラフを設定
    cols[1].line_chart(df.loc[str_start_date: str_end_date][stocks],
                       width=700,
                       use_container_width=False)

すると以下のような配置ができます。

空のコンテナ: st.empty

st.empty()を使うことで、要素を自由に置き換えたり削除することが可能になります

例えば、最初はテキスト情報を表示していますが、それをグラフに置き換えたりすることができます。

例を見てみましょう。

以下では、graph_areaという変数にst.empty()を設定しています。

これによりgraph_areaを自由に入れ替えることができ、ここではテキスト情報やボタンを押すことでグラフを表示、削除といったことができるようにしています。

import time
cols = st.columns(2)
graph_button = cols[0].button('グラフ描画')
delete_button = cols[1].button('グラフを削除')

graph_area = st.empty()
graph_area.subheader("ここにグラフを挿入します。")

if graph_button:
     graph_area.subheader("グラフ描画中 ...")
     time.sleep(2)
     graph_area.line_chart(df[['スノーピーク', '楽天', 'トヨタ']])

if delete_button:
     graph_area.subheader("deleted!!")

まとめ

以上で、レイアウトの設定は終了です。

これらにより、少し複雑なレイアウトを持つダッシュボードなどが作れるようになったのではないでしょうか?

次回は、状態の表示について見ていきたいと思います。

では!!

-streamlit入門, データ可視化
-, ,