mcpField
S
streamlit

streamlit

github.com/silvainfm数据与数据库3307 次安装13 周前更新
代码仓库

关于 streamlit

Streamlit 是用于数据科学和机器学习的 Python 交互式 Web 应用框架。此技能涵盖仪表板、可视化、控件及常见应用构建方式。

主要功能

  1. 01构建交互式 Python Web 应用
  2. 02数据图表与可视化
  3. 03控件与表单处理
  4. 04多页面应用结构
  5. 05缓存与会话状态

适用场景

  1. 01构建数据仪表板
  2. 02探索上传的数据集
  3. 03制作机器学习演示原型
  4. 04分享交互式分析

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/silvainfm/claude-skills --skill streamlit

安装后在 Claude Code 中输入/streamlit确认已加载。

附带文件references/api_reference.md

详细介绍

Streamlit

概述

Streamlit 是一个 Python 框架,可用于快速构建和部署面向数据科学和机器学习的交互式 Web 应用。只需使用 Python,即可创建精美的 Web 应用,无需具备前端开发经验。代码更改后,应用会自动实时更新。

何时使用此技能

在用户出现以下需求时启用:

  • 想要构建 Web 应用、仪表板或数据可视化工具
  • 明确提到 Streamlit
  • 需要创建 ML/AI 演示或原型
  • 想要交互式地可视化数据
  • 请求数据探索工具
  • 需要交互式控件(滑块、按钮、文件上传)
  • 想要与利益相关者分享分析结果

安装和设置

检查是否已安装 Streamlit:

python3 -c "import streamlit; print(streamlit.__version__)"

如果尚未安装:

pip3 install streamlit

创建并运行第一个应用:

# Create app.py with Streamlit code
streamlit run app.py

应用会自动在浏览器中打开,地址为 http://localhost:8501

基本应用结构

每个 Streamlit 应用都遵循这一简单模式:

import streamlit as st

# Set page configuration (must be first Streamlit command)
st.set_page_config(
    page_title="My App",
    page_icon="📊",
    layout="wide"
)

# Title and description
st.title("My Data App")
st.write("Welcome to my interactive dashboard!")

# Your app code here
# Streamlit automatically reruns from top to bottom when widgets change

核心功能

1. 显示文本和数据
import streamlit as st, pandas as pd
# Text elements
st.title("Main Title")
st.header("Section Header")
st.subheader("Subsection Header")
st.text("Fixed-width text")
st.markdown("**Bold** and *italic* text")
st.caption("Small caption text")

# Code blocks
st.code("""
def hello():
    print("Hello, World!")
""", language="python")

# Display data
df = pd.DataFrame({
    'Column A': [1, 2, 3],
    'Column B': [4, 5, 6]
})

st.dataframe(df)  # Interactive table
st.table(df)      # Static table
st.json({'key': 'value'})  # JSON data

# Metrics
st.metric(
    label="Revenue",
    value="$1,234",
    delta="12%"
)
2. 交互式控件
import streamlit as st
# Text input
name = st.text_input("Enter your name")
email = st.text_input("Email", type="default")
password = st.text_input("Password", type="password")
text = st.text_area("Long text", height=100)

# Numbers
age = st.number_input("Age", min_value=0, max_value=120, value=25)
slider_val = st.slider("Select a value", 0, 100, 50)
range_val = st.slider("Select range", 0, 100, (25, 75))

# Selections
option = st.selectbox("Choose one", ["Option 1", "Option 2", "Option 3"])
options = st.multiselect("Choose multiple", ["A", "B", "C", "D"])
radio = st.radio("Pick one", ["Yes", "No", "Maybe"])

# Checkboxes
agree = st.checkbox("I agree to terms")
show_data = st.checkbox("Show raw data")

# Buttons
if st.button("Click me"):
    st.write("Button clicked!")

# Date and time
date = st.date_input("Select date")
time = st.time_input("Select time")

# File upload
uploaded_file = st.file_uploader("Choose a file", type=['csv', 'xlsx', 'txt'])
if uploaded_file is not None:
    df = pd.read_csv(uploaded_file)
    st.dataframe(df)

# Download button
st.download_button(
    label="Download data",
    data=df.to_csv(index=False),
    file_name="data.csv",
    mime="text/csv"
)
3. 图表和可视化
import streamlit as st
import pandas as pd, numpy as np, matplotlib.pyplot as plt
import plotly.express as px
# Sample data
df = pd.DataFrame({
    'x': range(10),
    'y': np.random.randn(10)
})

# Streamlit native charts
st.line_chart(df)
st.area_chart(df)
st.bar_chart(df)

# Scatter plot with map data
map_data = pd.DataFrame(
    np.random.randn(100, 2) / [50, 50] + [37.76, -122.4],
    columns=['lat', 'lon']
)
st.map(map_data)

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

# Plotly (interactive)
fig = px.scatter(df, x='x', y='y', title="Interactive Plotly Chart")
st.plotly_chart(fig, use_container_width=True)

# Altair, Bokeh, and other libraries also supported
4. 布局和容器
import streamlit as st
# Columns
col1, col2, col3 = st.columns(3)
with col1:
    st.header("Column 1")
    st.write("Content here")
with col2:
    st.header("Column 2")
    st.write("More content")
with col3:
    st.header("Column 3")
    st.write("Even more")

# Tabs
tab1, tab2, tab3 = st.tabs(["Overview", "Data", "Settings"])
with tab1:
    st.write("Overview content")
with tab2:
    st.write("Data content")
with tab3:
    st.write("Settings content")

# Expander (collapsible section)
with st.expander("Click to expand"):
    st.write("Hidden content that can be expanded")

# Container
with st.container():
    st.write("This is inside a container")
    st.write("Another line")

# Sidebar
st.sidebar.title("Sidebar")
st.sidebar.selectbox("Choose option", ["A", "B", "C"])
st.sidebar.slider("Sidebar slider", 0, 100)
5. 状态和进度
import streamlit as st, time
# Success, info, warning, error messages
st.success("Success! Everything worked.")
st.info("This is an informational message.")
st.warning("This is a warning.")
st.error("This is an error message.")

# Progress bar
progress_bar = st.progress(0)
for i in range(100):
    time.sleep(0.01)
    progress_bar.progress(i + 1)

# Spinner (loading indicator)
with st.spinner("Processing..."):
    time.sleep(3)
st.success("Done!")

# Balloons (celebration)
st.balloons()

# Snow (celebration)
# st.snow()
6. 使用缓存提升性能
import streamlit as st, pandas as pd, time

# Cache data loading (persists across reruns)
@st.cache_data
def load_data():
    time.sleep(2)  # Simulate slow data load
    return pd.read_csv('large_file.csv')

# Cache resource (connections, models)
@st.cache_resource
def load_model():
    # Load ML model (expensive operation)
    return load_my_model()

# Use cached data
df = load_data()  # Only loads once, then cached
model = load_model()  # Cached globally

st.write(f"Loaded {len(df)} rows")
7. 会话状态(持久化数据)
import streamlit as st

# Initialize session state
if 'count' not in st.session_state:
    st.session_state.count = 0

# Increment counter
if st.button("Increment"):
    st.session_state.count += 1

st.write(f"Count: {st.session_state.count}")

# Store user data across reruns
if 'user_data' not in st.session_state:
    st.session_state.user_data = {}

name = st.text_input("Name")
if name:
    st.session_state.user_data['name'] = name
    st.write(f"Hello, {st.session_state.user_data['name']}!")

常见模式

模式 1:数据仪表板
import streamlit as st, pandas as pd, plotly.express as px

st.set_page_config(page_title="Sales Dashboard", layout="wide")

# Sidebar filters
st.sidebar.header("Filters")
date_range = st.sidebar.date_input("Date Range", [])
category = st.sidebar.multiselect("Category", ["A", "B", "C"])

# Load data
@st.cache_data
def load_sales_data():
    return pd.read_csv('sales_data.csv')

df = load_sales_data()

# Apply filters
if date_range:
    df = df[df['date'].between(date_range[0], date_range[1])]
if category:
    df = df[df['category'].isin(category)]

# Metrics row
col1, col2, col3, col4 = st.columns(4)
col1.metric("Total Revenue", f"${df['revenue'].sum():,.0f}")
col2.metric("Orders", f"{len(df):,}")
col3.metric("Avg Order", f"${df['revenue'].mean():.2f}")
col4.metric("Top Product", df['product'].mode()[0])

# Charts
col1, col2 = st.columns(2)
with col1:
    st.subheader("Revenue by Category")
    fig = px.bar(df.groupby('category')['revenue'].sum().reset_index(),
                 x='category', y='revenue')
    st.plotly_chart(fig, use_container_width=True)

with col2:
    st.subheader("Revenue Trend")
    fig = px.line(df.groupby('date')['revenue'].sum().reset_index(),
                  x='date', y='revenue')
    st.plotly_chart(fig, use_container_width=True)

# Data table
with st.expander("View Raw Data"):
    st.dataframe(df)
模式 2:数据探索器
import streamlit as st, pandas as pd, plotly.express as px

st.title("📊 Data Explorer")

# File upload
uploaded_file = st.file_uploader("Upload CSV", type=['csv'])

if uploaded_file:
    df = pd.read_csv(uploaded_file)

    # Show basic info
    st.subheader("Dataset Overview")
    col1, col2, col3 = st.columns(3)
    col1.metric("Rows", len(df))
    col2.metric("Columns", len(df.columns))
    col3.metric("Memory", f"{df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")

    # Column selection
    st.subheader("Explore Data")
    columns = st.multiselect("Select columns", df.columns.tolist(), default=df.columns.tolist()[:5])

    if columns:
        st.dataframe(df[columns])

        # Statistics
        st.subheader("Statistics")
        st.write(df[columns].describe())

        # Visualization
        st.subheader("Visualize")
        col1, col2 = st.columns(2)

        with col1:
            x_col = st.selectbox("X-axis", columns)
        with col2:
            y_col = st.selectbox("Y-axis", columns)

        chart_type = st.radio("Chart Type", ["Scatter", "Line", "Bar"])

        if chart_type == "Scatter":
            fig = px.scatter(df, x=x_col, y=y_col)
        elif chart_type == "Line":
            fig = px.line(df, x=x_col, y=y_col)
        else:
            fig = px.bar(df, x=x_col, y=y_col)

        st.plotly_chart(fig, use_container_width=True)
模式 3:多页面应用

使用以下文件结构创建多页面应用:

app/
├── main.py
└── pages/
    ├── 1_📊_Dashboard.py
    ├── 2_📈_Analytics.py
    └── 3_⚙️_Settings.py

主页面(main.py):

import streamlit as st
st.set_page_config(page_title="Multi-Page App", page_icon="🏠")

st.title("Welcome to My App")
st.sidebar.success("Select a page above.")

st.markdown("""
This is the home page. Navigate using the sidebar.
""")

页面会自动显示在侧边栏中。每个页面都是一个独立的 Python 文件。

表单处理

import streamlit as st
# Forms prevent rerun on every widget change
with st.form("my_form"):
    st.write("Fill out the form")

    name = st.text_input("Name")
    age = st.number_input("Age", min_value=0, max_value=120)
    favorite_color = st.selectbox("Favorite Color", ["Red", "Green", "Blue"])

    # Form submit button
    submitted = st.form_submit_button("Submit")

    if submitted:
        st.write(f"Name: {name}")
        st.write(f"Age: {age}")
        st.write(f"Color: {favorite_color}")

最佳实践

  1. 使用缓存 - 使用 @st.cache_data 和 @st.cache_resource 缓存耗时操作
  2. 使用会话状态实现持久化 - 使用 st.session_state 在重新运行时保留数据
  3. 使用容器组织内容 - 使用列、标签页和展开器,让布局更加整洁
  4. 使用表单处理多个输入 - 收集多个输入时,使用表单避免重新运行
  5. 为仪表板使用宽屏布局 - 为仪表板使用 st.set_page_config(layout="wide")
  6. 使用侧边栏放置控件 - 将筛选器和设置放在侧边栏中
  7. 显示进度指示器 - 耗时操作时显示旋转指示器

常见问题

问题:每次交互都会重新运行应用

使用 st.form() 批量处理输入,或使用 st.session_state 控制行为。

问题:性能缓慢

缓存耗时操作:

@st.cache_data
def expensive_computation(param):
    # Your code here
    return result
问题:状态无法持久化

使用会话状态:

if 'my_var' not in st.session_state:
    st.session_state.my_var = initial_value

资源

评论

支持 Markdown