Streamlit 中文全面教程:从入门到精通
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 stst.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 pltst.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) + 1value = np.sin(current_time * frequency) * amplitudenoise = 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 pdst.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 += 1data = pd.DataFrame({'时间': [time.ctime()],'值': [np.random.randn()]})# 更新数据data_container.table(data)
8.2 部署和共享 Streamlit 应用
Streamlit 应用可以通过多种方式部署和共享:
本地共享:
streamlit run your_script.py
- 适用于本地网络内共享
- 可通过
--server.address
和--server.port
参数配置网络地址和端口
Streamlit Sharing:
- 免费的托管服务,适用于公开共享
- 需要 GitHub 账户,将代码推送到 GitHub
- 限制:每月250MB流量,只能有一个同时活动的应用
Streamlit Cloud:
- 付费服务,提供更多流量和计算资源
- 支持同时部署多个应用
- 提供更好的性能和可靠性
Heroku 部署:
# 创建 requirements.txt streamlit==1.27.0 python==3.9.*# 创建 Procfile web: sh setup.sh
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 stst.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 = 0st.write("会话状态可以存储任意Python对象:")
st.write(st.session_state) # 显示所有会话状态
9.3 从 CSV 文件动态创建表单
import streamlit as st
import pandas as pdst.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 = columnvalue = 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 最佳实践总结
结构组织:
- 使用
st.title
、st.header
和st.subheader
创建清晰的层次结构 - 利用
st.sidebar
组织导航和过滤选项
- 使用
性能优化:
- 使用
@st.cache
缓存耗时计算和数据加载 - 避免在主循环中执行密集计算
- 使用
状态管理:
- 使用
st.session_state
管理组件之间的状态 - 对于复杂应用,考虑使用状态管理库
- 使用
错误处理:
- 使用
st.error
、st.warning
和st.info
提供用户反馈 - 添加 try/except 块处理潜在的异常
- 使用
响应式设计:
- 使用
st.columns
和st.expander
创建响应式布局 - 测试不同屏幕尺寸下的应用表现
- 使用
10. 与 Gradio 等其他工具的对比
特性 | Streamlit | Gradio | 说明 |
---|---|---|---|
易用性 | 简单易学,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,构建出色的数据应用!