0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🔰Streamlit超入門ハンドブック

Posted at

1. Python超入門

すでにPython経験がある人はこの章を流し見でOK。

1.1 変数・型・表示

# 1_hello_python.py
name = "Enzo"
age = 12
pi = 3.14
print(name, age, pi)

1.2 条件分岐・ループ・関数

# 1_basics.py
def grade(score):
    if score >= 90:
        return "A"
    elif score >= 80:
        return "B"
    return "C"

scores = [72, 88, 95]
for s in scores:
    print(s, grade(s))

1.3 仮想環境とパッケージ

# 端末で:プロジェクト用ディレクトリへ移動して
python -m venv .venv
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate

pip install streamlit pandas numpy matplotlib altair

2. 最初のStreamlit(最短ルート)

2.1 Hello, Streamlit!

# 2_hello_streamlit.py
import streamlit as st

st.title("Hello, Streamlit! 🚀")
st.write("はじめてのWebアプリ")

起動:

streamlit run 2_hello_streamlit.py

2.2 再実行(Rerun)モデルを掴む

# 2_rerun_model.py
import streamlit as st

st.title("再実行モデル入門")

name = st.text_input("お名前", "")
st.write("こんにちは,", name or "名無しさん")

count = st.number_input("回数", 0, 10, 0)
if st.button("実行"):
    st.success(f"実行しました x {count}")

st.info("入力やボタン操作のたびに、このスクリプトは最初から実行されます。")

3. 部品(ウィジェット)総ざらい

ここを押さえると一気に作れる幅が広がる
代表カテゴリごとに最小コードでざっと使い心地を掴みます。

3.1 テキストと装飾

# 3_texts.py
import streamlit as st
st.title("タイトル")
st.header("見出し")
st.subheader("サブ見出し")
st.text("等幅テキスト")
st.markdown("**太字** *斜体* `コード`")
st.code("print('コードブロック')", language="python")
st.latex(r"\int x^2 dx")
st.caption("補足説明・注意書きに")
st.divider()

3.2 入力ウィジェット(単発入力)

# 3_inputs_basic.py
import streamlit as st

name = st.text_input("名前")
age = st.number_input("年齢", min_value=0, step=1)
agree = st.checkbox("規約に同意する")
color = st.selectbox("", ["red", "green", "blue"])
many = st.multiselect("複数選択", ["A","B","C"])
day = st.date_input("日付")
tm  = st.time_input("時間")

st.write(name, age, agree, color, many, day, tm)

3.3 ボタン・リンク・ダウンロード

# 3_buttons_links.py
import streamlit as st

if st.button("計算する", type="primary"):
    st.success("計算しました!")
st.download_button("CSVをDL", data="a,b\n1,2\n", file_name="sample.csv")
st.link_button("ヘルプを見る", "https://docs.streamlit.io/")

3.4 フォーム(まとめて送信)

# 3_form.py
import streamlit as st

with st.form("profile"):
    c1, c2 = st.columns(2)
    with c1:
        name = st.text_input("氏名")
        age  = st.number_input("年齢", 0, 120, 20)
    with c2:
        email = st.text_input("メール")
        langs = st.multiselect("言語", ["Python", "JS", "Go"])
    ok = st.form_submit_button("登録する")
    if ok:
        st.success(f"登録完了: {name}, {age}, {email}, {langs}")

3.5 チャットUI要素(下準備)

# 3_chat_primer.py
import streamlit as st

st.title("チャットUI(素振り)")

if "messages" not in st.session_state:
    st.session_state.messages = []

for m in st.session_state.messages:
    with st.chat_message(m["role"]):
        st.write(m["content"])

if prompt := st.chat_input("メッセージを入力"):
    st.session_state.messages.append({"role":"user","content":prompt})
    with st.chat_message("user"):
        st.write(prompt)
    # ダミー応答
    reply = f"{prompt}」を受け取りました。"
    st.session_state.messages.append({"role":"assistant","content":reply})
    with st.chat_message("assistant"):
        st.write(reply)

4. レイアウト:列・タブ・サイドバー・コンテナ

# 4_layouts.py
import streamlit as st
st.title("レイアウト図鑑")

# 列
c1, c2, c3 = st.columns([1,2,1])
with c1: st.metric("PV", 1234, 56)
with c2: st.line_chart({"x":[1,2,3,4], "y":[1,4,9,16]})
with c3: st.progress(0.6)

# タブ
tab1, tab2 = st.tabs(["📈 分析", "⚙️ 設定"])
with tab1: st.area_chart({"x":[1,2,3], "y":[3,2,5]})
with tab2: st.toggle("ダークモード")

# サイドバー
st.sidebar.header("メニュー")
st.sidebar.radio("ページ", ["ホーム","分析","設定"])

# エクスパンダー
with st.expander("詳細を開く"):
    st.write("ここに補足情報")

5. データ表示・編集:dataframe / data_editor / column_config

5.1 表示:st.dataframe

# 5_dataframe.py
import streamlit as st
import pandas as pd

df = pd.DataFrame({
    "city":["Tokyo","Osaka","Nagoya","Fukuoka"],
    "temp":[18,17,16,20],
    "hum":[0.55,0.60,0.58,0.65],
})
st.dataframe(df, use_container_width=True)

5.2 編集:st.data_editor

# 5_data_editor.py
import streamlit as st
import pandas as pd

df = pd.DataFrame({"task":["A","B","C"], "done":[False,False,True]})
edited = st.data_editor(df, num_rows="dynamic")
st.write("編集結果", edited)

5.3 列の表現力:column_config 概要

# 5_column_config.py
import streamlit as st
import pandas as pd

df = pd.DataFrame({
    "name":["A","B"], 
    "link":["https://example.com","https://streamlit.io"],
    "score":[0.8, 0.95],
})

cfg = {
    "name": st.column_config.TextColumn("名前", help="任意のテキスト"),
    "link": st.column_config.LinkColumn("リンク"),
    "score": st.column_config.NumberColumn("スコア", min_value=0.0, max_value=1.0, step=0.01),
}

st.dataframe(df, column_config=cfg)

6. 可視化(標準+Altair/Matplotlib)

# 6_charts.py
import streamlit as st
import pandas as pd
import altair as alt
import matplotlib.pyplot as plt

df = pd.DataFrame({"x": range(1, 11)})
df["y"] = [v*v for v in df["x"]]

st.subheader("標準チャート")
st.line_chart(df, x="x", y="y")
st.area_chart(df, x="x", y="y")
st.bar_chart(df, x="x", y="y")

st.subheader("Altair")
chart = alt.Chart(df).mark_line().encode(x="x", y="y")
st.altair_chart(chart, use_container_width=True)

st.subheader("Matplotlib")
fig, ax = plt.subplots()
ax.plot(df["x"], df["y"])
ax.set_title("Matplotlib line")
st.pyplot(fig)

7. 状態管理・キャッシュ

7.1 セッション状態

# 7_session_state.py
import streamlit as st
if "count" not in st.session_state:
    st.session_state.count = 0
st.write("カウント:", st.session_state.count)
if st.button("増やす"): st.session_state.count += 1
if st.button("リセット"): st.session_state.count = 0

7.2 キャッシュ(データ/リソース)

# 7_cache.py
import streamlit as st, time

@st.cache_data
def slow_sum(n):
    time.sleep(1); return sum(range(n+1))

n = st.slider("n", 1000, 50000, 10000, step=1000)
st.write("結果:", slow_sum(n))

class Client: 
    def __init__(self, token): self.token = token
    def call(self, x): return f"hello {x} with {self.token}"

@st.cache_resource
def get_client(): return Client("SECRET")
client = get_client()
st.write(client.call("world"))

8. ファイルI/O(アップロード・ダウンロード)

# 8_io.py
import streamlit as st, pandas as pd, io

uploaded = st.file_uploader("CSVを選択", type="csv")
if uploaded:
    df = pd.read_csv(uploaded); st.dataframe(df)

csv = "name,score\nA,80\nB,90\n"
st.download_button("結果をDL", data=csv, file_name="result.csv", mime="text/csv")

9. 生成AIチャットUI(スケルトン→評価UI)

# 9_chat_app.py
import streamlit as st
st.title("チャットUI(骨組み)")

if "messages" not in st.session_state: st.session_state.messages=[]
for m in st.session_state.messages:
    with st.chat_message(m["role"]): st.write(m["content"])

if prompt := st.chat_input("メッセージを入力"):
    st.session_state.messages.append({"role":"user","content":prompt})
    with st.chat_message("user"): st.write(prompt)
    # ここで任意のLLM APIを呼ぶ
    reply = f"ダミー応答: {prompt}"
    with st.chat_message("assistant"): st.write(reply)
    st.session_state.messages.append({"role":"assistant","content":reply})
# 9_review_feedback.py
import streamlit as st
st.title("応答の検証/修正")
if "answer" not in st.session_state: st.session_state.answer = "サンプル応答。改善してください。"
st.text_area("AIの応答", key="answer", height=120)
fb = st.feedback("thumbs")
if fb is not None: st.toast(f"フィードバック: {fb}")

10. ステータスと進捗の見せ方

# 10_status.py
import streamlit as st, time, random
with st.status("処理中...", expanded=True) as status:
    st.write("前処理..."); time.sleep(0.5)
    st.write("推論..."); time.sleep(1.0)
    st.write("後処理..."); time.sleep(0.5)
    status.update(label="完了!", state="complete")

st.success("成功しました") if random.random()>0.5 else st.warning("注意が必要です")

11. 秘密情報・接続

# .streamlit/secrets.toml
[api]
key = "YOUR_API_KEY"
# 11_secrets.py
import streamlit as st
api_key = st.secrets["api"]["key"]
st.write("APIキー長:", len(api_key))

接続はst.connectionを前提に定義して使い回します(SQL/Snowflakeなど)。


12. ページ分割・構成

myapp/
  ├─ Home.py
  └─ pages/
      ├─ 1_📊_Dashboard.py
      └─ 2_⚙️_Settings.py
# Home.py
import streamlit as st
st.title("ホーム")
st.write("左上のメニューからページを切り替えられます。")

13. テスト(UI操作を自動化)

# 13_counter.py
import streamlit as st
if "count" not in st.session_state: st.session_state.count = 0
st.write(f"カウント: {st.session_state.count}")
if st.button("増やす"): st.session_state.count += 1
# 13_test_counter.py
from streamlit.testing.v1 import AppTest
def test_counter():
    at = AppTest.from_file("13_counter.py").run()
    at.button[0].click().run()
    assert any("カウント: 1" in t.value for t in at.text)

14. ミニプロジェクト集(すぐ使える雛形)

14.1 CSV探索ダッシュボード

# 14_csv_explorer.py
import streamlit as st, pandas as pd, io
st.title("CSV Explorer")
upl = st.file_uploader("CSVを選択", type="csv")
if upl: df = pd.read_csv(upl)
else:
    st.info("サンプルを使用")
    df = pd.read_csv(io.StringIO("city,temp,hum\nTokyo,18,0.55\nOsaka,17,0.60\nNagoya,16,0.58\nFukuoka,20,0.65\n"))
st.dataframe(df)
cols = st.multiselect("可視化列", [c for c in df.columns if df[c].dtype!="O"])
if cols: st.bar_chart(df[cols])
st.download_button("CSV保存", data=df.to_csv(index=False), file_name="export.csv")

14.2 生成AI風Q&Aボット

# 14_qa_bot.py
import streamlit as st; from datetime import datetime
st.title("Q&Aボット(ダミー)")
if "messages" not in st.session_state: st.session_state.messages=[]
if "system" not in st.session_state: st.session_state.system = "あなたは親切なアシスタントです。"
with st.expander("システム指示"): st.session_state.system = st.text_area("役割", st.session_state.system)
for m in st.session_state.messages:
    with st.chat_message(m["role"]): st.write(m["content"])
if prompt := st.chat_input("質問を入力"):
    st.session_state.messages.append({"role":"user","content":prompt})
    with st.chat_message("user"): st.write(prompt)
    reply = f"[{datetime.now().strftime('%H:%M:%S')}] {st.session_state.system} → 回答: {prompt[:20]}..."
    with st.chat_message("assistant"): st.write(reply)
    st.session_state.messages.append({"role":"assistant","content":reply})

14.3 KPIダッシュボード(多タブ)

# 14_kpi_tabs.py
import streamlit as st, pandas as pd
st.title("KPIダッシュボード")
tab1, tab2 = st.tabs(["月次", "週次"])
df = pd.DataFrame({"日付": pd.date_range("2023-01-01", periods=10),
                   "売上": [1000,1200,900,1500,1300,1800,1700,1600,1900,2000]})
with tab1: st.line_chart(df.set_index("日付"))
with tab2:
    df["増減"] = df["売上"].diff()
    st.bar_chart(df.set_index("日付")["増減"])

15. つまずきやすいポイント(チェックリスト)

  • ボタンは押した瞬間だけTrue。継続値はst.session_stateへ。
  • 入力中の画面チラつきが嫌ならフォームでまとめて送信。
  • 重い処理は@st.cache_data/@st.cache_resourceで再利用。
  • 表は表示→st.dataframe、編集→st.data_editor
  • レイアウトは列→タブ→サイドバーの順で整理。
  • 公開前に最小テストを1本用意して回帰を防止。
  • 機密はsecrets.tomlに置いてコードに直書きしない。

付録A:よく使うスニペット

import streamlit as st, time
st.toast("保存しました ✅"); st.caption("補足テキスト"); st.divider()
bar = st.progress(0); 
for i in range(100): time.sleep(0.01); bar.progress(i+1)
# HTMLを最小限で
import streamlit as st
st.html("<p style='color:tomato'>HTMLレンダリング</p>")
# カラム幅の使い分け
import streamlit as st
left, main = st.columns([1,3]); 
with left: st.write("サイド"); 
with main: st.write("メイン")

おわりに

小さく作って、すぐ動かして、少しずつ磨いていきましょう。
困ったらこのファイルのサンプルをコピペして、あなたのデータに置き換えるだけでOKです。
良いアプリ作りを!🚀

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?