你有没有盯着电子表格看,直到眼花缭乱?
我当然有过。
我们花几个小时清洗数据,分析趋势,并寻找那个黄金洞察。
但接下来是困难的部分。
我们必须展示它。
通常,这意味着静态的 PowerPoint 幻灯片或 Excel 图表的截图。
兴奋感瞬间消失。
你的受众不想看静态表格。
他们想要与数据互动。
他们想问,“如果我改变这个变量会发生什么?”或者“X 地区的情况看起来怎么样?”
这就是数据叙事发挥作用的地方。
而且你不需要成为 Web 开发人员就能构建一个让他们这样做的工具。
今天,我将向你展示如何将一个简单的数据集转化为一个完全互动的 Web 应用程序。
我们将使用 Python 和一个感觉像魔法一样的库:Streamlit。
为什么我极力推崇 Streamlit

我曾经害怕构建仪表板。
在过去,如果我想分享模型或可视化,我必须学习 Flask 或 Django。
我必须与 HTML、CSS 和 JavaScript 搏斗。
对于只想用 Python 编写代码的数据科学家来说,这简直是一场噩梦。
然后我发现了 Streamlit。
Streamlit 能在几分钟内将数据脚本转化为可共享的 Web 应用。
全部使用纯 Python。
不需要前端经验。
它在你的 Jupyter Notebook 和一个打磨好的产品之间架起了一座桥梁。
它允许你以极快的速度迭代。
你修改一行 Python 代码,点击保存,Web 应用就会立即更新。
在本教程中,我们代表 'My Core Pick',所以我们将专注于质量和速度。
让我们深入了解如何构建你的第一个叙事性仪表板。
搭建舞台:你的环境

在写任何一行代码之前,我们需要设置工作区。
我假设你已经安装了 Python。
如果没有,请从 python.org 获取最新版本。
我总是建议在虚拟环境中工作,以保持依赖项的清洁。
打开你的终端或命令提示符。
创建一个新文件夹用于你的项目。
bash
mkdir streamlit_dashboard
cd streamlit_dashboard
现在,创建一个虚拟环境。
bash
python -m venv venv
激活它(在 Windows 上使用 venv\Scripts\activate,在 Mac/Linux 上使用 source venv/bin/activate)。
现在,让我们安装主角。
我们需要 Streamlit 用于应用,Pandas 用于数据操作,Plotly 用于漂亮的交互式图表。
bash
pip install streamlit pandas plotly
就是这样。
我们准备好编码了。
基础:加载你的数据

创建一个名为 app.py 的新文件。
在你最喜欢的代码编辑器中打开它(我使用 VS Code)。
让我们从导入库开始。
python
import streamlit as st
import pandas as pd
import plotly.express as px
现在,我们需要一个标题。
Streamlit 让这变得非常简单。
python
st.set_page_config(page_title="Sales Dashboard", layout="wide")
st.title("📊 Global Sales Narrative")
st.markdown("## Analyze sales performance across different regions.")
接下来,我们需要数据。
对于这个例子,让我们假设我们有一个名为 sales_data.csv 的 CSV 文件。
(你可以使用任何你有的数据集,或者在线下载一个 Superstore Sales 样本数据集)。
我们将编写一个函数来加载数据。
为什么要用函数?
因为我们要使用 Streamlit 的缓存机制。
缓存的力量
每次用户与 Streamlit 应用交互(点击按钮,更改过滤器)时,整个脚本都会从头到尾重新运行。
如果你正在加载一个 500MB 的 CSV 文件,那将非常缓慢。
我们使用 @st.cache_data 装饰器来解决这个问题。
它告诉 Streamlit:“如果这个函数之前运行过,只需给我保存的结果。不要再次运行它。”
下面是我如何编写它:
```python
@st.cache_data
def get_data():
df = pd.read_csv("sales_data.csv")
# A little cleaning helps
df["Order Date"] = pd.to_datetime(df["Order Date"])
return df
df = get_data()
```
现在,让我们验证它是否工作。
我喜欢最初显示原始数据,只是为了检查逻辑是否正常。
python
if st.checkbox("Show Raw Data"):
st.dataframe(df.head())
保存你的文件。
去你的终端运行:
bash
streamlit run app.py
一个浏览器窗口将会弹出。
恭喜,你有一个正在运行的 Web 应用了。
构建叙事:侧边栏和过滤器
当听众选择路径时,故事会更好。
静态仪表板很无聊,因为它们试图向所有人展示所有内容。
我们希望给用户控制权。
Streamlit 提供了一个专门用于此目的的侧边栏。
它保持主区域清洁,用于可视化。
让我们为“地区”和“年份”添加一个过滤器。
创建侧边栏
我们使用 st.sidebar 将元素放在左侧。
```python
st.sidebar.header("Filter Options")
Create a multiselect for Region
region = st.sidebar.multiselect(
"Select Region:",
options=df["Region"].unique(),
default=df["Region"].unique()
)
```
现在,我们需要根据这个选择实际过滤 dataframe。
这就是交互发生的地方。
python
df_selection = df.query("Region == @region")
如果用户从侧边栏中移除“North America”,df_selection 会立即更新。
让我们验证数据是否有反应。
我们可以在主页面的顶部显示一些顶级指标(KPIs)。
显示关键绩效指标 (KPIs)
我喜欢使用 st.metric 组件。
它看起来很专业,并且突出了重要的数字。
让我们根据过滤后的数据计算总销售额和平均评分。
```python
total_sales = int(df_selection["Sales"].sum())
average_rating = round(df_selection["Rating"].mean(), 1)
left_column, right_column = st.columns(2)
with left_column:
st.metric(label="Total Sales", value=f"${total_sales:,}")
with right_column:
st.metric(label="Average Rating", value=f"{average_rating} ⭐")
```
注意到 st.columns(2) 了吗?
这是我们管理布局的方式。
它将屏幕分成两个等宽的列。
它打破了垂直流,使仪表板看起来是经过设计的,而不仅仅是堆砌在屏幕上。
可视化故事
现在我们要让数据对用户输入做出反应。
是时候将其可视化了。
虽然 Streamlit 有基本的图表,但我更喜欢 Plotly Express。
Plotly 图表默认是交互式的。
你可以悬停在数据点上,放大,并将图表下载为 PNG。
条形图
让我们回答这个问题:“哪条产品线表现最好?”
我们将创建一个显示按产品线销售额的条形图。
```python
sales_by_product = (
df_selection.groupby(by=["Product Line"]).sum()[["Sales"]].sort_values(by="Sales")
)
fig_product_sales = px.bar(
sales_by_product,
x="Sales",
y=sales_by_product.index,
orientation="h",
title="Sales by Product Line",
color_discrete_sequence=["#0083B8"] * len(sales_by_product),
template="plotly_white",
)
```
现在我们有了图形对象(fig_product_sales)。
我们需要在 Streamlit 中渲染它。
python
st.plotly_chart(fig_product_sales, use_container_width=True)
use_container_width=True 参数至关重要。
它确保图表扩展以填充列或屏幕的宽度。
这使得应用在不同屏幕尺寸上看起来都具有响应性。
时间序列
每个数据故事都需要一条时间线。
让我们展示销售额随时间变化的趋势。
这有助于识别季节性或突然的下降。
```python
Group by month
df_selection["month_year"] = df_selection["Order Date"].dt.to_period("M")
line_chart_data = df_selection.groupby(df_selection["month_year"].astype(str))["Sales"].sum().reset_index()
fig_sales_over_time = px.line(
line_chart_data,
x="month_year",
y="Sales",
title="Sales Over Time",
template="plotly_white"
)
st.plotly_chart(fig_sales_over_time, use_container_width=True)
```
现在,当你更改侧边栏中的地区时,条形图和折线图都会立即更新。
用户正在探索故事,而不仅仅是阅读它。
打磨用户体验
我们已经实现了功能。
但一个专业的仪表板需要一点打磨。
在 'My Core Pick',我们相信好与卓越的区别在于细节。
隐藏默认样式
Streamlit 在右上角自带一个“汉堡”菜单,在底部有一个“Made with Streamlit”页脚。
为了获得干净、专业的外观,我通常使用 CSS 注入来隐藏这些。
是的,我说过我们不需要 CSS,但这只是我保留的一个微小的可选片段。
python
hide_st_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
</style>
"""
st.markdown(hide_st_style, unsafe_allow_html=True)
添加上下文
不要只展示图表。
告诉用户他们在看什么。
使用 st.markdown 添加评论或解释数据中的异常。
例如,在折线图下方,你可以添加:
python
st.markdown("---")
st.caption("Note: Sales dipped in Q2 due to supply chain shortages in the North region.")
这种上下文将原始数字转化为实际的商业智能。
部署:分享你的故事
你建立了它。它在本地运行。
但它被困在你的笔记本电脑上。
要让你的团队或世界看到它,你需要部署它。
目前最简单的方法是 Streamlit Community Cloud。
工作流程如下:
-
创建 requirements.txt 文件。 这告诉服务器要安装哪些库。
在终端运行:pip freeze > requirements.txt。
-
将代码推送到 GitHub。 创建一个仓库并上传你的 app.py,sales_data.csv 和 requirements.txt。
-
注册 Streamlit Cloud。 将其连接到你的 GitHub 账户。
-
选择你的仓库。 点击“Deploy”(部署)。
大约两分钟后,你将拥有一个实时 URL。
你可以将该链接通过电子邮件发送给你的老板、客户,或发布在 LinkedIn 上。
他们可以在手机或笔记本电脑上打开它。
他们端不需要任何安装。
结论
我们刚刚从一个静态 CSV 文件变成了一个完全互动的、已部署的 Web 应用程序。
而且我们只用了不到 100 行 Python 代码。
这就是 Streamlit 的力量。
它使数据可视化民主化。
它允许数据科学家成为全栈开发人员,而无需陡峭的学习曲线。
你的数据有一个故事要讲。
不要把它扼杀在电子表格里。
给它一个声音。
构建仪表板,部署它,并让你的用户自己探索叙事。
我鼓励你这个周末试一试。
找一个你关心的数据集——也许是你的 Spotify 收听历史或你的健身追踪数据。
为自己建立一个仪表板。
一旦你开始构建对自己有反应的工具,你将再也不想回到静态幻灯片了。