关于 streamlit
Streamlit 是用于数据科学和机器学习的 Python 交互式 Web 应用框架。此技能涵盖仪表板、可视化、控件及常见应用构建方式。
主要功能
- 01构建交互式 Python Web 应用
- 02数据图表与可视化
- 03控件与表单处理
- 04多页面应用结构
- 05缓存与会话状态
适用场景
- 01构建数据仪表板
- 02探索上传的数据集
- 03制作机器学习演示原型
- 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}")
最佳实践
- 使用缓存 - 使用
@st.cache_data和@st.cache_resource缓存耗时操作 - 使用会话状态实现持久化 - 使用
st.session_state在重新运行时保留数据 - 使用容器组织内容 - 使用列、标签页和展开器,让布局更加整洁
- 使用表单处理多个输入 - 收集多个输入时,使用表单避免重新运行
- 为仪表板使用宽屏布局 - 为仪表板使用
st.set_page_config(layout="wide") - 使用侧边栏放置控件 - 将筛选器和设置放在侧边栏中
- 显示进度指示器 - 耗时操作时显示旋转指示器
常见问题
问题:每次交互都会重新运行应用
使用 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
资源
- references/api_reference.md:常用 Streamlit 组件快速参考
- 官方文档:https://docs.streamlit.io/
- API 参考:https://docs.streamlit.io/develop/api-reference
- 示例库:https://streamlit.io/gallery
- 社区:https://discuss.streamlit.io/
评论
支持 Markdown