1. Streamlit 基本介绍和特点

1.1 什么是 Streamlit

Streamlit 是一个开源的 Python 库,专为数据科学家和机器学习工程师设计,旨在快速构建数据应用。通过它,你可以用少量的 Python 代码创建交互式的数据可视化应用,无需任何前端开发经验。

核心优势:

  • 零前端门槛:无需学习 HTML、CSS 或 JavaScript([1†])
  • 快速开发:几分钟内就能将 Python 脚本转换为可分享的网页应用([17†])
  • 动态交互:自动支持代码修改后的实时刷新
  • 美观界面:内置现代化 UI 设计,自动处理样式和布局

1.2 Streamlit 的应用场景

Streamlit 适用于多种数据科学和机器学习场景:

  • 数据探索和分析工具
  • 模型可视化与演示
  • 实时交互式数据应用
  • 机器学习项目部署
  • 与大模型结合的交互式应用([2†])

作为一个开源项目,Streamlit 由 Streamlit, Inc. 开发并维护,其使命是"简化数据应用的创建过程"([6†])。

2. 安装方法和环境配置

2.1 基本安装

安装 Streamlit 非常简单,只需一条 pip 命令:

pip install streamlit

2.2 创建第一个 Streamlit 应用

创建名为 hello_streamlit.py 的文件:

import streamlit as st

st.title("你好,Streamlit!")
st.write("这是你的第一个 Streamlit 应用。")

运行应用:

streamlit run hello_streamlit.py

运行后,Streamlit 会自动打开浏览器,显示你的第一个应用([10†])。

2.3 开发环境推荐

为避免环境冲突,建议使用以下方式创建隔离环境:

# 创建虚拟环境
python -m venv streamlit_env

# 激活环境(Windows)
streamlit_env\Scripts\activate

# 激活环境(macOS/Linux)
source streamlit_env/bin/activate

# 安装 Streamlit
pip install streamlit

3. 基础使用方法和 API

3.1 基本结构

Streamlit 应用的基本结构非常简单,所有你编写的 streamlit 函数调用都会按顺序从上到下渲染在页面上。

import streamlit as st

# 标题
st.title("应用标题")

# 文本内容
st.write("这是一些文本内容")

# 显示数据
import pandas as pd
data = pd.DataFrame({
    '列1': [1, 2, 3],
    '列2': ['A', 'B', 'C']
})
st.write("数据框示例:")
st.dataframe(data)

3.2 常用基础函数

函数用途示例
st.title()设置页面标题st.title("数据分析结果")
st.header()添加主标题st.header("分析摘要")
st.subheader()添加副标题st.subheader("数据概览")
st.write()显示文本、数据或图表st.write("Hello world")
st.markdown()显示 Markdown 格式文本st.markdown("## 自定义格式标题")

4. 核心组件和 Widgets 使用

Streamlit 提供了丰富的交互式组件(widgets),无需前端知识即可实现复杂交互。

4.1 输入类组件

# 文本输入
user_name = st.text_input("请输入姓名", "你的名字")
st.write(f"你好,{user_name}!")

# 数字输入
number = st.number_input("输入一个数字", min_value=1, max_value=100, value=50)
st.write(f"你输入的数字是: {number}")

# 日期时间选择
import datetime
today = st.date_input("选择日期", datetime.date.today())
st.write(f"你选择的日期是: {today}")

current_time = st.time_input("选择时间", datetime.time(12, 0))
st.write(f"你选择的时间是: {current_time}")

4.2 选择类组件

# 下拉框
options = ["选项1", "选项2", "选项3"]
selected_option = st.selectbox("选择一个选项", options)
st.write(f"你选择了: {selected_option}")

# 多选框
selected_options = st.multiselect("选择多个选项", options)
st.write(f"你选择了: {selected_options}")

# 复选框
agree = st.checkbox("我同意条款")
st.write(f"同意条款: {agree}")

# 单选按钮
radio_choice = st.radio("选择一个选项", ("选项A", "选项B", "选项C"))
st.write(f"你选择了: {radio_choice}")

# 滑块
slider_value = st.slider("选择一个值", 0, 100, 50)
st.write(f"滑块值: {slider_value}")

4.3 按钮和事件

# 普通按钮
if st.button("点击我"):
    st.write("按钮被点击了!")

# 禁用按钮
disabled_button = st.button("禁用按钮", disabled=True)

# 根据条件显示内容
show_content = st.checkbox("显示高级设置")
if show_content:
    st.write("这是仅当复选框选中时才显示的内容")

5. 页面布局和样式定制

5.1 基本布局原理

Streamlit 是自上而下渲染的,组件在页面上的排列顺序与代码执行顺序一致([38†])。对于更复杂的布局需求,Streamlit 提供了多种容器和布局组件。

5.2 侧边栏

侧边栏是集中放置导航和控制选项的常用区域:

# 在侧边栏添加元素
with st.sidebar:
    st.title("侧边栏")
    selected_model = st.selectbox("选择模型", ["模型A", "模型B", "模型C"])
    process_button = st.button("处理数据")
    
st.write(f"从侧边栏选择的模型: {selected_model}")

5.3 列布局

使用 st.columns() 可以创建多列布局([25†]):

# 三列布局
col1, col2, col3 = st.columns(3)

with col1:
    st.write("第一列")
    st.slider("滑块1", 0, 100)
    
with col2:
    st.write("第二列")
    st.selectbox("选择", ["A", "B", "C"])
    
with col3:
    st.write("第三列")
    st.number_input("数字输入")

5.4 可展开内容

使用 st.expander() 可以创建可折叠的内容区域:

with st.expander("点击展开详细信息"):
    st.write("这是折叠的内容")
    st.dataframe({
        '列1': [1, 2, 3],
        '列2': ['详情1', '详情2', '详情3']
    })

5.5 高级布局技巧

# 自定义宽度的列
col_main, col_sidebar = st.columns([0.75, 0.25])

with col_main:
    st.write("主内容区")
    
with col_sidebar:
    st.write("侧边区")

# 使用容器创建复杂布局
container = st.container()
container.write("这是容器内的内容")

# 临时占位符
placeholder = st.empty()
with placeholder:
    st.write("这段内容可以被更新")
    
# 更新占位符内容
with placeholder:
    st.write("内容已更新")

6. 数据可视化和图表创建

6.1 使用 Matplotlib

import matplotlib.pyplot as plt
import numpy as np

# 生成示例数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 创建图表
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title("正弦波")
ax.set_xlabel("X 轴")
ax.set_ylabel("Y 轴")

# 在 Streamlit 中显示图表
st.pyplot(fig)

6.2 使用 Plotly 创建交互式图表

import plotly.graph_objects as go

# 生成示例数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 创建交互式图表
fig = go.Figure(data=go.Scatter(
    x=x, 
    y=y, 
    mode='lines+markers',
    name='正弦波'
))

fig.update_layout(
    title="交互式正弦波",
    xaxis_title="X 轴",
    yaxis_title="Y 轴"
)

# 在 Streamlit 中显示交互式图表
st.plotly_chart(fig)

6.3 使用 Altair

import altair as alt
import pandas as pd

# 创建示例数据
source = pd.DataFrame({
    'x': range(10),
    'y': np.random.randn(10)
})

# 创建 Altair 图表
chart = alt.Chart(source).mark_point().encode(
    x='x',
    y='y',
    tooltip=['x', 'y']
).properties(
    width=600,
    height=400
).interactive()

# 在 Streamlit 中显示
st.altair_chart(chart, use_container_width=True)

6.4 显示数据表格

import pandas as pd

# 创建示例数据
data = pd.DataFrame({
    '姓名': ['张三', '李四', '王五'],
    '年龄': [25, 30, 35],
    '城市': ['北京', '上海', '广州']
})

# 显示数据表
st.dataframe(data)

# 或使用表格格式显示
st.table(data)

# 高亮显示特定行
st.dataframe(data.style.highlight_max(axis=0))

7. 机器学习和数据科学应用案例

7.1 机器学习模型演示

下面是一个使用 Streamlit 构建机器学习模型演示的示例:

import streamlit as st
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 页面标题
st.title("Iris 花种分类模型")

# 加载数据集
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=0.2, random_state=42
)

# 训练模型
model = RandomForestClassifier()
model.fit(X_train, y_train)

# 用户输入
st.subheader("输入特征值")
sepal_length = st.slider("花萼长度 (cm)", 4.0, 8.0, 5.5)
sepal_width = st.slider("花萼宽度 (cm)", 2.0, 5.0, 3.5)
petal_length = st.slider("花瓣长度 (cm)", 1.0, 7.0, 4.5)
petal_width = st.slider("花瓣宽度 (cm)", 0.1, 3.0, 1.5)

# 预测
input_data = np.array([[sepal_length, sepal_width, petal_length, petal_width]])
prediction = model.predict(input_data)
probability = model.predict_proba(input_data)

# 显示结果
st.subheader("预测结果")
st.write(f"预测的花种: {iris.target_names[prediction][0]}")

# 显示概率
st.subheader("分类概率")
probability_df = pd.DataFrame({
    '花种': iris.target_names,
    '概率': probability[0]
}).sort_values('概率', ascending=False)

st.dataframe(probability_df.style.format({'概率': '{:.2%}'}))

# 模型性能
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
st.write(f"模型准确率: {accuracy:.2f}")

7.2 实时数据处理应用

import streamlit as st
import numpy as np
import time
import pandas as pd
import matplotlib.pyplot as plt

st.title("实时数据监控")

# 创建数据存储区
if 'data' not in st.session_state:
    st.session_state.data = pd.DataFrame(columns=['时间', '值'])

# 侧边栏参数设置
with st.sidebar:
    frequency = st.slider("频率 (Hz)", 0.1, 5.0, 1.0, 0.1)
    amplitude = st.slider("振幅", 0.1, 5.0, 1.0, 0.1)
    noise_level = st.slider("噪声水平", 0.0, 1.0, 0.2, 0.1)
    reset = st.button("重置数据")

if reset:
    st.session_state.data = pd.DataFrame(columns=['时间', '值'])

# 显示图表
fig, ax = plt.subplots()
ax.set_title("实时数据")
ax.set_xlabel("时间")
ax.set_ylabel("值")
ax.set_xlim(0, 100)
ax.set_ylim(-5, 5)

chart = st.pyplot(fig)

# 生成并显示数据
def generate_data():
    while True:
        current_time = len(st.session_state.data) + 1
        value = np.sin(current_time * frequency) * amplitude
        noise = np.random.normal(0, noise_level)
        value += noise
        
        # 限制数据点数量
        if len(st.session_state.data) > 100:
            st.session_state.data = st.session_state.data.iloc[1:]
        
        st.session_state.data = st.session_state.data.append(
            {'时间': current_time, '值': value},
            ignore_index=True
        )
        
        yield value

# 更新图表
data_gen = generate_data()

with chart:
    ax.cla()  # 清除上次的图表
    ax.plot(st.session_state.data['时间'], st.session_state.data['值'], 'b-')
    ax.set_xlim(0, max(10, len(st.session_state.data)*1.1))
    ax.set_ylim(
        min(st.session_state.data['值'].min() - 1, -5), 
        max(st.session_state.data['值'].max() + 1, 5)
    )
    ax.grid(True)

8. 实时数据更新和共享部署

8.1 自动刷新

Streamlit 支持多种自动刷新方式,实现实时数据更新:

import streamlit as st
import time
import numpy as np
import pandas as pd

st.title("实时数据更新示例")

# 选择刷新方式
refresh_mode = st.radio(
    "选择刷新模式",
    ["手动刷新", "定时刷新 (1秒)", "流式更新"]
)

if refresh_mode == "手动刷新":
    st.write("点击下方按钮刷新数据")
    if st.button("刷新数据"):
        st.write(f"数据已刷新: {time.ctime()}")
        
elif refresh_mode == "定时刷新 (1秒)":
    st.write("应用将在每秒自动刷新")
    st.write(f"最后一次刷新: {time.ctime()}")
    
else:  # 流式更新
    st.write("流式更新数据:")
    
    # 创建一个容器用于显示数据
    data_container = st.empty()
    
    # 创建一个计数器
    if 'counter' not in st.session_state:
        st.session_state.counter = 0
    
    # 模拟流式数据
    st.session_state.counter += 1
    data = pd.DataFrame({
        '时间': [time.ctime()],
        '值': [np.random.randn()]
    })
    
    # 更新数据
    data_container.table(data)

8.2 部署和共享 Streamlit 应用

Streamlit 应用可以通过多种方式部署和共享:

  1. 本地共享

    streamlit run your_script.py
    
    • 适用于本地网络内共享
    • 可通过 --server.address 和 --server.port 参数配置网络地址和端口
  2. Streamlit Sharing

    • 免费的托管服务,适用于公开共享
    • 需要 GitHub 账户,将代码推送到 GitHub
    • 限制:每月250MB流量,只能有一个同时活动的应用
  3. Streamlit Cloud

    • 付费服务,提供更多流量和计算资源
    • 支持同时部署多个应用
    • 提供更好的性能和可靠性
  4. Heroku 部署

    # 创建 requirements.txt
    streamlit==1.27.0
    python==3.9.*
    
    # 创建 Procfile
    web: sh setup.sh
    
  5. AWS/其他云服务

    • 可以部署在任何支持 Python 运行的服务器上
    • 需要配置域名和 SSL 证书实现 HTTPS 访问

9. 高级功能和最佳实践

9.1 数据缓存优化性能

使用 @st.cache 装饰器缓存计算结果,提高应用性能:

import streamlit as st
import time
import numpy as np

# 缓存密集计算函数的结果
@st.cache
def compute_heavy_data(n):
    """模拟耗时计算过程"""
    time.sleep(5)  # 模拟耗时计算
    return np.random.randn(n, n)

st.title("性能优化示例")

n = st.slider("选择矩阵大小", 100, 1000, 500)
st.write(f"正在计算 {n}x{n} 矩阵...")

# 第一次调用会较慢,后续会使用缓存
data = compute_heavy_data(n)
st.write(f"计算完成! 数据形状: {data.shape}")

# 显示前几个元素
st.dataframe(data[:5, :5])

9.2 会话状态管理

Streamlit 提供了 st.session_state 对象用于在组件之间共享状态:

import streamlit as st

st.title("会话状态示例")

# 初始化计数器
if 'counter' not in st.session_state:
    st.session_state.counter = 0

# 显示当前值
st.write(f"当前值: {st.session_state.counter}")

# 增加按钮
if st.button("增加"):
    st.session_state.counter += 1

# 减少按钮
if st.button("减少"):
    st.session_state.counter -= 1

# 重置按钮
if st.button("重置"):
    st.session_state.counter = 0

st.write("会话状态可以存储任意Python对象:")
st.write(st.session_state)  # 显示所有会话状态

9.3 从 CSV 文件动态创建表单

import streamlit as st
import pandas as pd

st.title("从CSV动态创建表单")

# 上传CSV文件
uploaded_file = st.file_uploader("选择一个CSV文件", type=["csv"])
if uploaded_file is not None:
    # 读取CSV数据
    df = pd.read_csv(uploaded_file)
    
    # 显示数据预览
    st.subheader("数据预览")
    st.dataframe(df.head())
    
    # 创建表单字段
    st.subheader("填写表单")
    form_data = {}
    
    # 为每列创建字段
    for column in df.columns:
        label = column
        value = df[column].iloc[0] if not df[column].isna().iloc[0] else ""
        
        # 根据列类型创建不同的输入字段
        if pd.api.types.is_string_dtype(df[column]):
            form_data[column] = st.text_input(label, value)
        elif pd.api.types.is_numeric_dtype(df[column]):
            form_data[column] = st.number_input(label, value)
        elif pd.api.types.is_bool_dtype(df[column]):
            form_data[column] = st.checkbox(label, value)
        else:
            form_data[column] = st.text_input(label, value)
    
    # 提交按钮
    if st.button("提交"):
        st.write("提交的数据:")
        st.write(form_data)

9.4 最佳实践总结

  1. 结构组织

    • 使用 st.titlest.header 和 st.subheader 创建清晰的层次结构
    • 利用 st.sidebar 组织导航和过滤选项
  2. 性能优化

    • 使用 @st.cache 缓存耗时计算和数据加载
    • 避免在主循环中执行密集计算
  3. 状态管理

    • 使用 st.session_state 管理组件之间的状态
    • 对于复杂应用,考虑使用状态管理库
  4. 错误处理

    • 使用 st.errorst.warning 和 st.info 提供用户反馈
    • 添加 try/except 块处理潜在的异常
  5. 响应式设计

    • 使用 st.columns 和 st.expander 创建响应式布局
    • 测试不同屏幕尺寸下的应用表现

10. 与 Gradio 等其他工具的对比

特性StreamlitGradio说明
易用性简单易学,API直观简单易用,专注于ML任务Streamlit更适合数据展示,Gradio更适合模型交互
布局控制通过with语句和容器组件自动生成界面,自定义有限Streamlit提供更精细的布局控制
开发速度两者都比传统Web开发快很多
社区支持活跃活跃Gradio被Hugging Face收购,有强大支持
适用场景数据科学应用、数据可视化机器学习模型演示、AI应用Streamlit更适合数据团队,Gradio更适合AI研究者
部署难度中等(需要配置服务器)低(支持streamlit sharing和gradio.app)Gradio在快速部署方面有优势

Streamlit 和 Gradio 都是优秀的低代码Web开发工具,选择哪个取决于你的具体需求:

  • 如果你专注于数据可视化和分析,Streamlit可能是更好的选择
  • 如果你专注于机器学习模型部署和AI应用,Gradio可能更适合

总结

Streamlit 是一个强大而易用的Python库,使数据科学家和机器学习工程师能够快速构建交互式Web应用,无需前端开发经验。通过本教程,我们介绍了Streamlit的核心功能、组件和高级特性,从基础安装到复杂应用案例,帮助你全面掌握这个工具。

通过 Streamlit,你可以专注于数据和业务逻辑,而不是前端代码,大幅提高开发效率。希望这个教程能帮助你快速上手 Streamlit,构建出色的数据应用!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐