『Plotly實戰(zhàn)指南』--Plotly與Streamlit結(jié)合實戰(zhàn)
關(guān)于Streamlit的介紹,可參考《玩轉(zhuǎn)Streamlit》系列
在當(dāng)今數(shù)據(jù)驅(qū)動的時代,快速構(gòu)建交互式工具并直觀地將數(shù)據(jù)分析結(jié)果交付給用戶,已成為數(shù)據(jù)應(yīng)用開發(fā)的核心需求。
無論是企業(yè)內(nèi)部的決策支持系統(tǒng),還是面向公眾的數(shù)據(jù)可視化平臺,都需要一種高效且靈活的開發(fā)方式。
Plotly和Streamlit的結(jié)合,正是滿足這一需求的完美解決方案。
Plotly作為一個強(qiáng)大的交互式圖表庫,支持多種圖表類型,能夠輕松創(chuàng)建動態(tài)且美觀的可視化效果。
而 Streamlit 是一個輕量級、低代碼的 Web 應(yīng)用框架,專注于簡化數(shù)據(jù)應(yīng)用的開發(fā)流程,讓開發(fā)者能夠快速構(gòu)建并部署交互式應(yīng)用。
二者的互補(bǔ)性顯而易見:
Plotly:支持40+交互式圖表類型,從基礎(chǔ)折線圖到 3D 曲面圖應(yīng)有盡有Streamlit:用純Python腳本即可創(chuàng)建Web應(yīng)用,部署時間從數(shù)周縮短到數(shù)小時
本文主要介紹如何結(jié)合Plotly和Streamlit開發(fā)動態(tài)數(shù)據(jù)應(yīng)用,并優(yōu)化其性能。
1. Streamlit應(yīng)用中嵌入Plotly圖表
1.1. 靜態(tài)圖表嵌入
將Plotly圖表嵌入Streamlit應(yīng)用的基礎(chǔ)方法是通過st.plotly_chart()函數(shù)直接渲染Plotly圖表。
這種方式簡單直接,能夠快速將圖表展示在頁面上。
以下是一個將折線圖和熱力圖嵌入 Streamlit 頁面的示例代碼:
import streamlit as st
import plotly.express as px
import pandas as pd
# 創(chuàng)建一個簡單的折線圖
df = pd.DataFrame({"x": [1, 2, 3, 4, 5], "y": [10, 11, 12, 13, 14]})
line_fig = px.line(df, x="x", y="y", title="折線圖示例")
# 創(chuàng)建一個熱力圖
heatmap_data = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})
heatmap_fig = px.imshow(heatmap_data, title="熱力圖示例")
# 在 Streamlit 中展示圖表
st.plotly_chart(line_fig)
st.plotly_chart(heatmap_fig)

1.2. 圖表與組件交互
Plotly圖表的強(qiáng)大之處不僅在于其靜態(tài)展示能力,更在于其動態(tài)交互性。
通過結(jié)合Streamlit的交互組件(如st.slider和st.selectbox),可以實現(xiàn)圖表參數(shù)的動態(tài)控制,從而為用戶提供更加靈活的可視化體驗。
以下是一個案例,展示如何通過用戶選擇的日期范圍實時更新K 線圖:
import streamlit as st
import plotly.graph_objects as go
import pandas as pd
# 獲取K線數(shù)據(jù)
data = pd.read_parquet(
r"/path/to/BTC-USDT_1h.parquet"
)
# 創(chuàng)建日期范圍選擇器
start_date = st.date_input("開始日期", value=data["candle_begin_time"].min())
end_date = st.date_input("結(jié)束日期", value=data["candle_begin_time"].max())
# 根據(jù)選擇的日期范圍篩選數(shù)據(jù)
filtered_data = data.query(
"candle_begin_time >= @start_date & candle_begin_time <= @end_date"
)
# 創(chuàng)建 K 線圖
fig = go.Figure(
data=[
go.Candlestick(
x=filtered_data.index,
open=filtered_data["open"],
high=filtered_data["high"],
low=filtered_data["low"],
close=filtered_data["close"],
)
]
)
fig.update_layout(title="K 線圖", xaxis_title="日期", yaxis_title="價格")
# 在 Streamlit 中展示圖表
st.plotly_chart(fig)

在這個示例中,用戶可以通過日期選擇器動態(tài)調(diào)整 K 線圖的顯示范圍,
而Plotly圖表會根據(jù)篩選后的數(shù)據(jù)實時更新,從而實現(xiàn)交互效果。
2. 數(shù)據(jù)驅(qū)動的交互式應(yīng)用
2.1. 上傳文件更新圖表
在實際應(yīng)用中,數(shù)據(jù)往往是動態(tài)的,用戶可能需要根據(jù)不同的條件來查看不同的數(shù)據(jù)視圖。
通過結(jié)合Streamlit的輸入組件(如st.file_uploader、st.selectbox和st.slider),可以實現(xiàn)數(shù)據(jù)的動態(tài)加載和圖表的動態(tài)更新。
以下是一個實戰(zhàn)案例,展示如何構(gòu)建一個動態(tài)銷售分析看板,支持按地區(qū)和產(chǎn)品類別篩選:
import streamlit as st
import plotly.express as px
import pandas as pd
# 上傳數(shù)據(jù)
uploaded_file = st.file_uploader("上傳銷售數(shù)據(jù)", type=["csv"])
if uploaded_file is not None:
data = pd.read_csv(uploaded_file)
# 提取地區(qū)和產(chǎn)品類別的列表
regions = data["地區(qū)"].unique()
products = data["產(chǎn)品類別"].unique()
# 創(chuàng)建篩選組件
selected_region = st.selectbox("選擇地區(qū)", regions)
selected_product = st.selectbox("選擇產(chǎn)品類別", products)
# 根據(jù)篩選條件過濾數(shù)據(jù)
filtered_data = data[(data["地區(qū)"] == selected_region) & (data["產(chǎn)品類別"] == selected_product)]
# 創(chuàng)建動態(tài)圖表
fig = px.bar(filtered_data, x="日期", y="銷售額", title="銷售分析")
st.plotly_chart(fig)
在這個示例中,用戶可以通過上傳數(shù)據(jù)文件,并選擇地區(qū)和產(chǎn)品類別,動態(tài)生成銷售分析圖表。
這種設(shè)計模式不僅提高了應(yīng)用的靈活性,還增強(qiáng)了用戶體驗。
2.2. 使用緩存優(yōu)化性能
在處理大量數(shù)據(jù)時,性能優(yōu)化是一個不可忽視的問題。
Streamlit提供了緩存機(jī)制,通過@st.cache_data裝飾器,可以避免重復(fù)加載和計算數(shù)據(jù),從而顯著提高應(yīng)用的性能。
以下是一個示例,展示如何通過緩存優(yōu)化數(shù)據(jù)處理和繪圖性能:
import streamlit as st
import plotly.express as px
import pandas as pd
# 緩存數(shù)據(jù)加載函數(shù)
@st.cache_data
def load_data(file):
return pd.read_csv(file)
# 緩存圖表生成函數(shù)
@st.cache_data
def create_chart(data):
return px.bar(data, x="日期", y="銷售額", title="銷售分析")
# 上傳數(shù)據(jù)
uploaded_file = st.file_uploader("上傳銷售數(shù)據(jù)", type=["csv"])
if uploaded_file is not None:
# 加載數(shù)據(jù)并緩存
data = load_data(uploaded_file)
# 創(chuàng)建篩選組件
selected_region = st.selectbox("選擇地區(qū)", data["地區(qū)"].unique())
selected_product = st.selectbox("選擇產(chǎn)品類別", data["產(chǎn)品類別"].unique())
# 根據(jù)篩選條件過濾數(shù)據(jù)
filtered_data = data[(data["地區(qū)"] == selected_region) & (data["產(chǎn)品類別"] == selected_product)]
# 生成圖表并緩存
fig = create_chart(filtered_data)
st.plotly_chart(fig)
在這個示例中,通過緩存數(shù)據(jù)加載和圖表生成的過程,可以避免重復(fù)計算,從而提高應(yīng)用的加載速度。
啟用緩存后,用戶在切換篩選條件時,圖表的更新速度會明顯加快。
緩存策略對比效果:
| 場景 | 未啟用緩存 | 啟用緩存 |
|---|---|---|
| 10MB CSV加載 | 1.2s | 0.05s |
| 復(fù)雜圖表生成 | 0.8s | 0.01s |
3. 總結(jié)
Plotly和Streamlit的結(jié)合為快速構(gòu)建兼具交互性與美觀的數(shù)據(jù)應(yīng)用提供了強(qiáng)大的支持。
通過組件聯(lián)動設(shè)計,可以實現(xiàn)靈活的用戶交互;
通過緩存優(yōu)化,可以顯著提高應(yīng)用的性能;
通過用戶友好的界面布局,可以提升用戶體驗。
這種組合不僅適用于數(shù)據(jù)分析和可視化,還可以擴(kuò)展到實時數(shù)據(jù)監(jiān)控、機(jī)器學(xué)習(xí)模型結(jié)果可視化等更多場景。

浙公網(wǎng)安備 33010602011771號