PythonでWebアプリ|Streamlitの基本&コンポーネントガイド
Streamlitを使ってPythonでウェブアプリケーションを作成する基本的な手順と、主要コンポーネントの使い方をチートシート形式でまとめました。この記事を読めば、Streamlitの基本的な操作から、各コンポーネントの特徴や利用方法(コンポーネントごとのサンプルコード付き)までを網羅的に理解することができます。
Streamlitとは
Streamlitは、Pythonで簡単にWebアプリケーションを作成できるオープンソースのライブラリです。
Streamlitを使用すると、Windows、MacOS、LinuxといったOSに依存せず、どの環境でも同じようにしてウェブアプリケーションを作成できます。簡単なGUIなら、streamlitを使って作成することができる、プラットフォーム依存もないので手軽にプロトタイプを作成することができます。
この記事では、Streamlitのインストール方法、基本的な使い方、そして提供されているGUIコンポーネントについて詳しく解説します。
streamlitの公式ドキュメント:https://docs.streamlit.io/

ちょっとしたGUI作成に最適
私は、AI系アプリのGUIとして使われていたのを見てStreamlitを知りました(それまでも何度か聞いたことはあったのですが、スルーしていました。関心を持ったのはAI系アプリがきっかけです)。
実際に使ってみると、AI系のアプリで、画像の物体検出結果を表示させたり、クラス分類の結果を表示させるといったアプリが作りやすい印象を受けました。
「Pythonで作ったコードに、ちょっとしたGUIを追加したい」という場合に、streamlitは向いていると感じます。プロトタイピングには最適ではないでしょうか。
一方、本格的なWebアプリ(REST APIを使ったアプリ)を作成する場合は、FastAPI, Django, Flaskなどのフレームワークを使うことをお勧めします。
インストール
anacondaでインストールする場合
anaconda, minicondaを使っていてインストールする場合は、コマンドラインで以下を実行します。
conda install -c conda-forge streamlit
自分のMacでは、pipではうまくインストールできなかったので、condaをインストールしているならこちらでインストールした方が良いです

試す場合は、仮想環境を作成することをお勧めします。以下のコマンドで仮想環境を作って、Activateできます
conda create -n streamlit
conda activate stremlit
pipでインストールする場合
pipでインストールする場合は、コマンドラインで以下のコマンドを実行します
pip install streamlit動作確認
正しくインストールできたかどうか、以下のコマンドで確認します。
正しくインストールできていれば、ブラウザが開いて下図のようなページが表示されます
streamlit hello
使い方
作成したアプリの起動(streamlit run)
作成したアプリケーションを起動するには、以下のコマンドを実行します。xxxx.pyは、作成したアプリのPythonファイルです。
コマンドを実行すると、ブラウザにアプリケーションの画面が表示されます。
streamlit run xxxx.pyライブラリのインポート
streamlitのライブラリをインポートします。ここでは、この記事で使っている他のライブラリも一緒にインポートしています。
streamlitは、import streamlit as stでインポートしています。streamlitの機能にアクセスする場合は、st.xxxx()という形でアクセスすることになります。
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
from PIL import Image
import random
import timeWrite文を用いた出力
st.write()を使えば、Pythonの変数や表、グラフなどをブラウザ上に表示できます。以下、表示の例を示します。
文字列(markdown)
st.write(str)で、文字列を出力できます。文字列はmarkdownとして扱われます。
例えば、以下のように文字列を与えると、見出しや強調、リスト、表といったものを簡単にブラウザに表示することができます。

markdown記法に慣れていないと使いにくく感じますが、慣れればちょっとした装飾を簡単にできるようになります
st.write(
"""
# これはH1です
## これはH2です
### これはH3です
これは**本文**です。
* リスト1
* リスト2
1. リスト1
2. リスト2
|A|B|C|
|:-|:-|:-:|
|one|2|3|
|two|5|6|
|thres|10|-|
""")
pandasの表
pandasの表もst.write()を使って出力するだけで表示することが可能です。
df = pd.DataFrame({"x":[1,2,3], "y":['a','b','c']})
st.write(df)
Pandasの表を編集したい場合には、以下のようにすれば編集可能になります。また、編集した結果も受け取ることができます。
edited_df = st.data_editor(df)
matplotlibのグラフ
matplotlibのグラフの表示もwrite()で行うことができます。
ただし、簡単なグラフであれば、後で説明するstreamlitのグラフ機能を使った方が良いと思います。
x = [i for i in range(100)]
y = [random.random() for _ in range(100)]
fig, ax = plt.subplots()
ax.plot(x, y)
st.write(fig)

とりあえず、write()だけでいろいろ表示することができます
基本コンポーネント
以下、streamlitで使えるGUIコンポーネントについて解説します。
文字列
文字列を表示させる関数です。
st.text("文字列です")
ボタン
ボタンを表示します。ボタンが押された場合は、戻り値にTrueが返ります。
click = st.button("Click")
if click :
st.write("ボタンが押されました: click = ", click)
スライダー
スライダーです。min_value、max_value、valueで最小・最大値と初期位置を指定できます。また、stepでスライダーの動き幅を設定できます。
st.write("## slider")
val = st.slider("値を設定してください", min_value = 0, max_value = 100, value = 50, step = 2)
st.write(f"スライダーの値={val}")
ラジオボタン
ラベルと、項目をタプル(またはリスト)で設定します。
ラジオボタンです。index=Noneを設定することで、どれも選ばれていない状態にできます。指定しない場合は、1番目が選ばれます
sel = st.radio(
"以下を選択してください",
("Aを選択", "Bを選択", "Cを選択"),
index = None,
)
if sel == None :
st.write("**どれかを選択してください**")
elif sel == "Aを選択" :
st.write(":rainbow[正解!]")
else :
st.write("不正解!")
選択ボックス(selectbox)
項目を選択するドロップダウンリストを表示します。
ラベル、項目の純で設定します。indexに設定された項目がデフォルトで選択された状態になります。placeholderは、何も選択されていない場合に表示されるテキストです。
option = st.selectbox(
"どれを選択しますか?",
("メール", "電話", "AIチャット"),
index=None,
placeholder="連絡手段を選んでください...",
)
st.write(f"選択は{option}ですね。")
テキスト入力
テキストの入力が1行の場合はtext_inputを使います。
ラベル、あらかじめ入力されている文字列を引数として渡します(あらかじめ入力されている文字列がない場合は空行となります)
placeholderは、何も選択されていない場合に表示されるテキストです。
input = st.text_input(
'意見を入力してください',
'サンプルの入力')
st.write(f"入力は「{input}」ですね")
input = st.text_input(
'意見を入力してください',
placeholder = 'ここに入力')
st.write(f"入力は「{input}」ですね")
st.write("## text area")
複数行のテキスト入力を行う場合は、text_areaを使います。
txt = st.text_area(
"感想をいれてください",
"たのしめました。また、よろしくお願いします",)
st.write(f":red[入力は以下の通りです]")
st.write(txt)
txt = st.text_area(
"感想をいれてください",
placeholder = 'ここに入力')
st.write(f":red[入力は以下の通りです]")
st.write(txt)
ダウンロード
ファイルのダウンロードも行うことができます。以下の例は、pandasのデータフレームをcsvに変換してダウンロードしています。
dataにダウンロードするデータを、file_nameにファイル名、mimeはMIMEタイプです。
MIMEタイプは、dataに合わせて設定します。MIMEタイプとしては、例えば、以下のようなものがあります。
| 文書の種類 | MIMEタイプ |
| JSON 形式 | application/json |
| カンマ区切り値 (CSV) | text/csv |
| ハイパーテキストマークアップ言語 (HTML) | text/html |
| JPEG 画像 | image/jpeg |
| MPEG 動画 | video/mpeg |
| MP3 音声 | audio/mpeg |
以下のコードで、CSVファイルでダウンロードのボタンをクリックすると、ファイルがダウンロードできます。
df = pd.DataFrame({"x":[1,2,3], "y":['a','b','c']})
st.write(df)
st.download_button(
label="CSVファイルでダウンロード",
data=df.to_csv().encode('utf-8'),
file_name='df.csv',
mime='text/csv',
)
アップロード
ファイルのアップロードも行うことが可能です。
以下の例では、画像をアップロードして表示させています。

アップロードできるファイルサイズに制限があります
uploaded_file = st.file_uploader("画像ファイルを選択してください", type=['png', 'jpg'])
if uploaded_file is not None:
img = Image.open(uploaded_file)
st.image(img, uploaded_file.name)

プログラム中でst.Imageを使っています。これは、画像を表示するコンポーネントです。
サイドバー
サイドバーを作ることも可能です。やり方はいくつかありますが、with st.sideberを使って、一気にGUIアイテムを配置するのが手軽です。

メインの画面と、サイドバーに同じものを貼り付けるとKeyエラーが発生することがあります。その場合は、引数keyで一意なKeyを設定すれば解決します
with st.sidebar :
sel2 = st.selectbox(
"どれを選択しますか?",
("メール", "電話", "AIチャット"),
index=None,
placeholder="連絡手段を選んでください...",
key = "sel2"
)

待ち時間表示(spinner)
処理中をくるくる回転するアニメーションで表示させるものです。以下のようなコードで利用します。
以下のコードでは、ボタンがクリックされると2秒間スピナーが回転します。
実際にこれを使う場合はtime.sleep(2)のかわりに、重い処理をここに記述します。
if st.button('処理を開始'):
with st.spinner('処理中です...'):
# ここに時間のかかる処理を書く
time.sleep(2)
st.write('終了しました')

グラフ描画
グラフの描画についていくつかサンプルを用意しました
ライングラフ
x = [i for i in range(100)]
y = [random.random() for _ in range(100)]
df = pd.DataFrame({'x' : x , 'y' : y})
st.line_chart(df, x = 'x', y = 'y')
散布図
x = [i for i in range(100)]
y = [random.random() for _ in range(100)]
df = pd.DataFrame({'x' : x , 'y' : y})
st.scatter_chart(df, x = 'x', y = 'y')
棒グラフ
x = [i for i in range(100)]
y = [random.random() for _ in range(100)]
df = pd.DataFrame({'x' : x , 'y' : y})
st.bar_chart(df, x = 'x', y = 'y')
TIPS(便利な機能)
データの保持について
streamlitは、ボタンをクリックしたり、GUI操作をするとすべてのデータがリセットされてしまいます。上の例のグラフなどは、ボタンがクリックされる度に乱数が変化し、内容が変化してしまいます。
データを保存するには、st.session_stateを利用します。
以下は、使い方の例です。
if "x" not in st.session_state :
st.session_state.x = random.random()
st.write(f"xは{st.session_state.x}です")デバッグに便利なRun on save機能
streamlit run xxxx.pyで起動したアプリケーションのコードを書き換えるときに、毎回再起動するのは面倒です。
streamlitでは、動かしながら確認する機能が用意されています。
これを有効にするには、「Settings」で、「Run on save」をチェックしておきます。
① Webアプリの左上にあるSettingsを選択します。

② SettingsのRun on saveのチェックボックスをチェックします。

Deployについて
streamlitで作成したアプリは、デプロイすることでWebアプリとして公開することもできます。今回解説した機能を一覧表示するアプリもデプロイしてみました。
試してみる場合はここをクリックしてください。

deployするには、githubのアカウントなどが必要になります。今回はデプロイについては解説を省略します。
まとめ
WebベースのGUIを作るのに便利。ちょっとしたGUIを作る場合は、これがよいかも(理由:windows, mac, linuxで同じように表示できる)

