Streamlit 入门指南:几行 Python 做出数据应用
一、开头痛点:想把数据变成应用,却被前端劝退
很多 Python 工程师都遇到过这样的尴尬:用 pandas 跑出一串漂亮的分析结果,用 matplotlib 画出几张图,最后只能截图发群里,或者用 Jupyter Notebook 自己看。想把它做成「别人打开网页就能用」的工具,就得学 HTML、CSS、JavaScript,再配一个 Flask/Django 后端------光是环境就劝退一大半人。
Streamlit 就是为解决这个问题而生的。它让你只用 Python 就能写出一个带交互、能实时刷新的 Web 应用,不用写一行前端代码。改完脚本保存,网页自动热更新。数据分析师、算法工程师、运维同学,都能在几十行代码内把脚本变成可分享的产品原型。
二、环境准备:一行命令装好
Streamlit 是纯 Python 库,支持 Python 3.8+。建议先用虚拟环境隔离依赖,避免污染全局:
bash
# 创建并激活虚拟环境(可选但推荐)
python -m venv .venv
source .venv/bin/activate # Windows 用 .venv\Scripts\activate
# 安装 Streamlit
pip install streamlit
装完验证一下版本,能正常打印就说明环境 OK:
python
# check_version.py
import streamlit as st
# 打印当前 Streamlit 版本,确认安装成功
print("Streamlit 版本:", st.__version__)
在终端运行 streamlit run check_version.py 会启动本地服务并自动打开浏览器,默认地址是 http://localhost:8501。本文所有示例都用这个端口访问。
三、最小可运行示例:Hello, Streamlit
我们先写一个「能跑起来」的最简应用,建立整体直觉:
python
# app.py
import streamlit as st
# st.title 渲染页面大标题
st.title("我的第一个 Streamlit 应用")
# st.write 是最通用的输出函数,能渲染文本、数字、DataFrame、图表等
st.write("你好,这是用纯 Python 写出来的网页!")
# 一个滑动条:返回当前数值,拖动时页面会实时重跑脚本
age = st.slider("请选择你的年龄", 0, 120, 25)
st.write("你选择的年龄是:", age)
运行 streamlit run app.py,拖动滑块,右侧数字会立刻跟着变。这背后有个关键机制:每次交互,整个脚本都会从上到下重跑一遍,Streamlit 再把新的输出映射到界面上。理解这一点,后面很多「坑」就迎刃而解了。
四、核心概念:控件、布局、状态与缓存
1) 输入控件(widgets) 控件函数会「返回」当前的值,你把它赋给变量即可:
python
name = st.text_input("你的名字", "张三") # 文本输入框
agree = st.checkbox("我同意条款") # 勾选框,返回布尔值
option = st.selectbox("选择城市", ["北京", "上海", "广州"]) # 下拉框
clicked = st.button("点我提交") # 按钮,点击的那次重跑返回 True
2) 布局(layout) 用 st.sidebar 把控件放到左侧栏,用 st.columns 做并排布局:
python
st.sidebar.title("筛选条件") # 侧边栏
threshold = st.sidebar.slider("阈值", 0, 100, 50)
col1, col2 = st.columns(2) # 两列并排
col1.metric("销量", 1280)
col2.metric("增长率", "12%")
3) 会话状态(session_state) 因为脚本每次都重跑,想让数据「跨重跑」保存,就要用 st.session_state:
python
if "count" not in st.session_state:
st.session_state.count = 0 # 只在首次初始化
if st.button("加一"):
st.session_state.count += 1
st.write("当前计数:", st.session_state.count)
4) 缓存(cache) 加载大文件或训练模型很慢,每次重跑都重来会卡死。@st.cache_data 把函数结果按入参缓存起来:
python
@st.cache_data
def load_data(path):
import pandas as pd
return pd.read_csv(path) # 同一 path 只真正读取一次
五、进阶用法:文件上传与图表联动
Streamlit 对 pandas、matplotlib、Plotly 等生态是原生友好的。下面演示「上传 CSV → 自动出图 → 用滑块过滤」的进阶组合:
python
import pandas as pd
import streamlit as st
uploaded = st.file_uploader("上传一个 CSV 文件", type="csv")
if uploaded is not None:
df = pd.read_csv(uploaded) # 直接把上传对象喂给 pandas
st.dataframe(df.head(20)) # 交互式表格,可排序
numeric_cols = df.select_dtypes("number").columns.tolist()
if numeric_cols:
col = st.selectbox("选择要画图的数值列", numeric_cols)
top_n = st.slider("显示前 N 行", 5, 50, 10)
st.line_chart(df[col].head(top_n)) # 内置折线图,无需额外配置
如果用 matplotlib 画图,记得用 st.pyplot() 承接:
python
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.hist(df[col], bins=20)
st.pyplot(fig) # 把 figure 交给 Streamlit 渲染
六、实战场景:一个迷你销售看板(完整代码)
把前面概念串起来,做一个能用的小应用:上传销售数据,按城市筛选,看趋势和汇总。
python
# dashboard.py
import pandas as pd
import streamlit as st
@st.cache_data
def load_data(uploaded_file):
"""读取上传的 CSV,缓存避免重复解析。"""
return pd.read_csv(uploaded_file)
st.set_page_config(page_title="销售看板", layout="wide")
st.title("📊 迷你销售看板")
uploaded = st.file_uploader("上传销售数据 CSV(需含 city、amount、date 列)", type="csv")
if uploaded is None:
st.info("请先上传一个 CSV 文件开始使用。")
st.stop() # 没上传就停止后续渲染
df = load_data(uploaded)
df["date"] = pd.to_datetime(df["date"]) # 转成日期类型,便于按时间画图
cities = st.sidebar.multiselect(
"选择城市", df["city"].unique(), default=list(df["city"].unique())[:3]
)
filtered = df[df["city"].isin(cities)]
col1, col2 = st.columns(2)
col1.metric("总销售额", f"{filtered['amount'].sum():,.0f}")
col2.metric("订单数", len(filtered))
st.subheader("销售额趋势")
st.line_chart(filtered.set_index("date")["amount"].resample("D").sum())
st.subheader("城市汇总")
st.dataframe(filtered.groupby("city")["amount"].sum().reset_index())
运行 streamlit run dashboard.py,上传一份带 city/amount/date 的 CSV,就能得到一个可筛选、可联动的销售看板。这已经是一个能交付给同事看的原型了。
七、常见坑与报错(附解决办法)
坑 1:ModuleNotFoundError: No module named 'streamlit' 现象:终端跑 streamlit run app.py 报找不到模块。 原因:装到了 A 环境,却用 B 环境的 Python 启动;或根本没装。 解决:确认安装和运行的解释器一致------which python / pip show streamlit 核对路径;虚拟环境下先 activate 再运行。
坑 2:端口 8501 被占用,自动跳到 8502/8503 现象:启动时提示 Port 8501 is already in use, trying 8502。 原因:上一次没关,或服务已在跑。 解决:要么关掉旧进程,要么显式指定端口:streamlit run app.py --server.port 8503。
坑 3:点了 st.button 后状态没记住 现象:在按钮回调里 +1,刷新后计数又变回初始值。 原因:脚本每次交互都从头重跑,button 点击只在「那一次」重跑返回 True,之后就重置;直接写变量无法跨重跑保存。 解决:用 st.session_state 持久化(见第四节),或用 st.checkbox / st.toggle 这类天然带状态的控件替代。
八、总结与下一步
Streamlit 的核心优势就一句话:把 Python 脚本直接变成可交互的 Web 应用,无需任何前端知识。本文覆盖了安装、最小示例、核心控件、布局与状态、缓存、文件上传,以及一个完整的销售看板实战。
下一步建议你:
- 用
@st.cache_resource缓存数据库连接或机器学习模型(适合不可变的大对象); - 把多个页面拆成
pages/目录,做成多页应用; - 用
streamlit deploy(Streamlit Community Cloud)免费托管,把原型分享给任何人。
动手把今天你的某个 pandas 脚本包一层 st. ,你就拥有了人生第一个数据应用。