streamlit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Streamlit

Streamlit

Overview

概述

Streamlit is a Python framework for rapidly building and deploying interactive web applications for data science and machine learning. Create beautiful web apps with just Python - no frontend development experience required. Apps automatically update in real-time as code changes.
Streamlit是一款用于快速构建和部署数据科学与机器学习交互式Web应用的Python框架。只需使用Python即可创建美观的Web应用,无需前端开发经验。代码更改时,应用会自动实时更新。

When to Use This Skill

何时使用该技能

Activate when the user:
  • Wants to build a web app, dashboard, or data visualization tool
  • Mentions Streamlit explicitly
  • Needs to create an ML/AI demo or prototype
  • Wants to visualize data interactively
  • Asks for a data exploration tool
  • Needs interactive widgets (sliders, buttons, file uploads)
  • Wants to share analysis results with stakeholders
当用户有以下需求时激活:
  • 想要构建Web应用、仪表板或数据可视化工具
  • 明确提到Streamlit
  • 需要创建机器学习/人工智能演示或原型
  • 想要交互式地可视化数据
  • 询问数据探索工具
  • 需要交互式组件(滑块、按钮、文件上传)
  • 想要与利益相关者分享分析结果

Installation and Setup

安装与设置

Check if Streamlit is installed:
bash
python3 -c "import streamlit; print(streamlit.__version__)"
If not installed:
bash
pip3 install streamlit
Create and run your first app:
bash
undefined
检查Streamlit是否已安装:
bash
python3 -c "import streamlit; print(streamlit.__version__)"
如果未安装:
bash
pip3 install streamlit
创建并运行你的第一个应用:
bash
undefined

Create app.py with Streamlit code

创建包含Streamlit代码的app.py

streamlit run app.py

The app opens automatically in your browser at `http://localhost:8501`
streamlit run app.py

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

Basic App Structure

基础应用结构

Every Streamlit app follows this simple pattern:
python
import streamlit as st
每个Streamlit应用都遵循以下简单模式:
python
import streamlit as st

Set page configuration (must be first Streamlit command)

设置页面配置(必须是第一个Streamlit命令)

st.set_page_config( page_title="My App", page_icon="📊", layout="wide" )
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!")
st.title("我的数据应用") st.write("欢迎来到我的交互式仪表板!")

Your app code here

你的应用代码

Streamlit automatically reruns from top to bottom when widgets change

当组件变化时,Streamlit会自动从顶部到底部重新运行代码

undefined
undefined

Core Capabilities

核心功能

1. Displaying Text and Data

1. 文本与数据展示

python
import streamlit as st, pandas as pd
python
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")
st.title("主标题") st.header("章节标题") st.subheader("子章节标题") st.text("固定宽度文本") st.markdown("加粗斜体文本") st.caption("小型说明文本")

Code blocks

代码块

st.code(""" def hello(): print("Hello, World!") """, language="python")
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
df = pd.DataFrame({ 'Column A': [1, 2, 3], 'Column B': [4, 5, 6] })
st.dataframe(df) # 交互式表格 st.table(df) # 静态表格 st.json({'key': 'value'}) # JSON数据

Metrics

指标卡片

st.metric( label="Revenue", value="$1,234", delta="12%" )
undefined
st.metric( label="收入", value="$1,234", delta="12%" )
undefined

2. Interactive Widgets

2. 交互式组件

python
import streamlit as st
python
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)
name = st.text_input("输入你的姓名") email = st.text_input("邮箱", type="default") password = st.text_input("密码", type="password") text = st.text_area("长文本输入", 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))
age = st.number_input("年龄", min_value=0, max_value=120, value=25) slider_val = st.slider("选择一个值", 0, 100, 50) range_val = st.slider("选择范围", 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"])
option = st.selectbox("选择一个选项", ["选项1", "选项2", "选项3"]) options = st.multiselect("选择多个选项", ["A", "B", "C", "D"]) radio = st.radio("选择一个", ["是", "否", "可能"])

Checkboxes

复选框

agree = st.checkbox("I agree to terms") show_data = st.checkbox("Show raw data")
agree = st.checkbox("我同意条款") show_data = st.checkbox("显示原始数据")

Buttons

按钮

if st.button("Click me"): st.write("Button clicked!")
if st.button("点击我"): st.write("按钮已点击!")

Date and time

日期与时间选择

date = st.date_input("Select date") time = st.time_input("Select time")
date = st.date_input("选择日期") time = st.time_input("选择时间")

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)
uploaded_file = st.file_uploader("选择文件", 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" )
undefined
st.download_button( label="下载数据", data=df.to_csv(index=False), file_name="data.csv", mime="text/csv" )
undefined

3. Charts and Visualizations

3. 图表与可视化

python
import streamlit as st
import pandas as pd, numpy as np, matplotlib.pyplot as plt
import plotly.express as px
python
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) })
df = pd.DataFrame({ 'x': range(10), 'y': np.random.randn(10) })

Streamlit native charts

Streamlit原生图表

st.line_chart(df) st.area_chart(df) st.bar_chart(df)
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)
map_data = pd.DataFrame( np.random.randn(100, 2) / [50, 50] + [37.76, -122.4], columns=['lat', 'lon'] ) st.map(map_data)

Matplotlib

Matplotlib图表

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

Plotly (interactive)

Plotly(交互式)

fig = px.scatter(df, x='x', y='y', title="Interactive Plotly Chart") st.plotly_chart(fig, use_container_width=True)
fig = px.scatter(df, x='x', y='y', title="交互式Plotly图表") st.plotly_chart(fig, use_container_width=True)

Altair, Bokeh, and other libraries also supported

同时支持Altair、Bokeh等其他库

undefined
undefined

4. Layout and Containers

4. 布局与容器

python
import streamlit as st
python
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")
col1, col2, col3 = st.columns(3) with col1: st.header("列1") st.write("这里是内容") with col2: st.header("列2") st.write("更多内容") with col3: st.header("列3") st.write("更多内容")

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")
tab1, tab2, tab3 = st.tabs(["概述", "数据", "设置"]) with tab1: st.write("概述内容") with tab2: st.write("数据内容") with tab3: st.write("设置内容")

Expander (collapsible section)

展开面板(可折叠章节)

with st.expander("Click to expand"): st.write("Hidden content that can be expanded")
with st.expander("点击展开"): st.write("可展开的隐藏内容")

Container

容器

with st.container(): st.write("This is inside a container") st.write("Another line")
with st.container(): st.write("这在容器内部") st.write("另一行内容")

Sidebar

侧边栏

st.sidebar.title("Sidebar") st.sidebar.selectbox("Choose option", ["A", "B", "C"]) st.sidebar.slider("Sidebar slider", 0, 100)
undefined
st.sidebar.title("侧边栏") st.sidebar.selectbox("选择选项", ["A", "B", "C"]) st.sidebar.slider("侧边栏滑块", 0, 100)
undefined

5. Status and Progress

5. 状态与进度

python
import streamlit as st, time
python
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.")
st.success("成功!一切正常。") st.info("这是一条信息提示。") st.warning("这是一条警告。") st.error("这是一条错误消息。")

Progress bar

进度条

progress_bar = st.progress(0) for i in range(100): time.sleep(0.01) progress_bar.progress(i + 1)
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!")
with st.spinner("处理中..."): time.sleep(3) st.success("完成!")

Balloons (celebration)

气球动画(庆祝效果)

st.balloons()
st.balloons()

Snow (celebration)

雪花动画(庆祝效果)

st.snow()

st.snow()

undefined
undefined

6. Caching for Performance

6. 缓存优化性能

python
import streamlit as st, pandas as pd, time
python
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')
@st.cache_data def load_data(): time.sleep(2) # 模拟缓慢的数据加载 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()
@st.cache_resource def load_model(): # 加载机器学习模型(耗时操作) 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")
undefined
df = load_data() # 仅加载一次,之后从缓存获取 model = load_model() # 全局缓存
st.write(f"已加载 {len(df)} 行数据")
undefined

7. Session State (Persistent Data)

7. 会话状态(持久化数据)

python
import streamlit as st
python
import streamlit as st

Initialize session state

初始化会话状态

if 'count' not in st.session_state: st.session_state.count = 0
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}")
if st.button("递增"): st.session_state.count += 1
st.write(f"计数: {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']}!")
undefined
if 'user_data' not in st.session_state: st.session_state.user_data = {}
name = st.text_input("姓名") if name: st.session_state.user_data['name'] = name st.write(f"你好, {st.session_state.user_data['name']}!")
undefined

Common Patterns

常见模式

Pattern 1: Data Dashboard

模式1:数据仪表板

python
import streamlit as st, pandas as pd, plotly.express as px

st.set_page_config(page_title="Sales Dashboard", layout="wide")
python
import streamlit as st, pandas as pd, plotly.express as px

st.set_page_config(page_title="销售仪表板", layout="wide")

Sidebar filters

侧边栏过滤器

st.sidebar.header("Filters") date_range = st.sidebar.date_input("Date Range", []) category = st.sidebar.multiselect("Category", ["A", "B", "C"])
st.sidebar.header("过滤器") date_range = st.sidebar.date_input("日期范围", []) category = st.sidebar.multiselect("类别", ["A", "B", "C"])

Load data

加载数据

@st.cache_data def load_sales_data(): return pd.read_csv('sales_data.csv')
df = load_sales_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)]
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])
col1, col2, col3, col4 = st.columns(4) col1.metric("总收入", f"${df['revenue'].sum():,.0f}") col2.metric("订单数", f"{len(df):,}") col3.metric("平均订单额", f"${df['revenue'].mean():.2f}") col4.metric("热门产品", 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)
col1, col2 = st.columns(2) with col1: st.subheader("按类别划分的收入") 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("收入趋势") 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)
undefined
with st.expander("查看原始数据"): st.dataframe(df)
undefined

Pattern 2: Data Explorer

模式2:数据探索器

python
import streamlit as st, pandas as pd, plotly.express as px

st.title("📊 Data Explorer")
python
import streamlit as st, pandas as pd, plotly.express as px

st.title("📊 数据探索器")

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)
undefined
uploaded_file = st.file_uploader("上传CSV文件", type=['csv'])
if uploaded_file: df = pd.read_csv(uploaded_file)
# 显示基本信息
st.subheader("数据集概述")
col1, col2, col3 = st.columns(3)
col1.metric("行数", len(df))
col2.metric("列数", len(df.columns))
col3.metric("内存占用", f"{df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")

# 列选择
st.subheader("探索数据")
columns = st.multiselect("选择列", df.columns.tolist(), default=df.columns.tolist()[:5])

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

    # 统计信息
    st.subheader("统计数据")
    st.write(df[columns].describe())

    # 可视化
    st.subheader("可视化")
    col1, col2 = st.columns(2)

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

    chart_type = st.radio("图表类型", ["散点图", "折线图", "柱状图"])

    if chart_type == "散点图":
        fig = px.scatter(df, x=x_col, y=y_col)
    elif chart_type == "折线图":
        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)
undefined

Pattern 3: Multi-Page App

模式3:多页面应用

Create a multi-page app with file structure:
app/
├── main.py
└── pages/
    ├── 1_📊_Dashboard.py
    ├── 2_📈_Analytics.py
    └── 3_⚙️_Settings.py
Main page (
main.py
):
python
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.
""")
Pages automatically appear in the sidebar. Each page is a separate Python file.
通过以下文件结构创建多页面应用:
app/
├── main.py
└── pages/
    ├── 1_📊_Dashboard.py
    ├── 2_📈_Analytics.py
    └── 3_⚙️_Settings.py
主页面(
main.py
):
python
import streamlit as st
st.set_page_config(page_title="多页面应用", page_icon="🏠")

st.title("欢迎来到我的应用")
st.sidebar.success("选择上方的页面。")

st.markdown("""
这是主页。请使用侧边栏导航。
""")
页面会自动显示在侧边栏中。每个页面都是一个独立的Python文件。

Form Handling

表单处理

python
import streamlit as st
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}")
undefined
with st.form("我的表单"): st.write("填写表单")
name = st.text_input("姓名")
age = st.number_input("年龄", min_value=0, max_value=120)
favorite_color = st.selectbox("最喜欢的颜色", ["红色", "绿色", "蓝色"])

# 表单提交按钮
submitted = st.form_submit_button("提交")

if submitted:
    st.write(f"姓名: {name}")
    st.write(f"年龄: {age}")
    st.write(f"颜色: {favorite_color}")
undefined

Best Practices

最佳实践

  1. Use caching - Cache expensive operations with
    @st.cache_data
    and
    @st.cache_resource
  2. Session state for persistence - Use
    st.session_state
    to persist data across reruns
  3. Organize with containers - Use columns, tabs, and expanders for clean layouts
  4. Forms for multiple inputs - Prevent reruns with forms when collecting multiple inputs
  5. Wide layout for dashboards - Use
    st.set_page_config(layout="wide")
    for dashboards
  6. Sidebar for controls - Put filters and settings in the sidebar
  7. Progress indicators - Show spinners for long operations
  1. 使用缓存 - 使用
    @st.cache_data
    @st.cache_resource
    缓存耗时操作
  2. 会话状态实现持久化 - 使用
    st.session_state
    在多次运行中保存数据
  3. 使用容器组织布局 - 使用列、标签页和展开面板实现整洁的布局
  4. 表单处理多输入 - 收集多个输入时使用表单避免频繁重运行
  5. 仪表板使用宽布局 - 对仪表板使用
    st.set_page_config(layout="wide")
  6. 侧边栏放置控件 - 将过滤器和设置放在侧边栏中
  7. 进度指示器 - 对长时间操作显示加载动画

Common Issues

常见问题

Issue: App reruns on every interaction

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

Use
st.form()
to batch inputs or
st.session_state
to control behavior.
使用
st.form()
批量处理输入,或使用
st.session_state
控制行为。

Issue: Slow performance

问题:性能缓慢

Cache expensive operations:
python
@st.cache_data
def expensive_computation(param):
    # Your code here
    return result
缓存耗时操作:
python
@st.cache_data
def expensive_computation(param):
    # 你的代码
    return result

Issue: State not persisting

问题:状态无法持久化

Use session state:
python
if 'my_var' not in st.session_state:
    st.session_state.my_var = initial_value
使用会话状态:
python
if 'my_var' not in st.session_state:
    st.session_state.my_var = initial_value

Resources

资源