我用 Python 給女朋友做了個(gè)選禮物看板!
↑ 關(guān)注 + 星標(biāo) ,每天學(xué)Python新技能
后臺(tái)回復(fù)【大禮包】送你Python自學(xué)大禮包

主要使用Excel和Python的Pandas 庫(kù)、Streamlit 庫(kù)、Plotly 庫(kù)進(jìn)行搭建可視化大屏。



一、前提準(zhǔn)備
本案例數(shù)據(jù)相對(duì)結(jié)構(gòu)化,僅用 Excel 結(jié)合 Pandas 做簡(jiǎn)單處理即可,Plotly 制作可視化圖表,Streamlit 搭建可視化頁(yè)面。
1.1 安裝依賴庫(kù)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas==1.1.0
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple plotly==4.14.3
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple streamlit==0.86.0
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple openpyxl==3.0.6
1.2 Plotly
官方文檔地址:https://plot.ly/python/plotly-express/
Plotly Express 是一個(gè)新的高級(jí) Python 可視化庫(kù),它為復(fù)雜的圖表提供了一個(gè)簡(jiǎn)單的語(yǔ)法。Plotly 交互效果明顯優(yōu)于 Python 的兩大傳統(tǒng)可視化庫(kù) Matplotlib 和 Seaborn。相比 Power BI 和 Tableau 等 BI 工具,Plotly 無(wú)法勝任數(shù)據(jù)清洗、關(guān)系模型等功能,僅是一個(gè)可視化工具。但與 Python 其它庫(kù),比如今天使用的 Streamlit 配合,可以創(chuàng)造出像網(wǎng)站、可視化大屏、機(jī)器學(xué)習(xí)工具等各種精彩的應(yīng)用。
1.3 Streamlit
官方文檔地址:https://docs.streamlit.io/
Streamlit 是一個(gè)功能強(qiáng)大,完全免費(fèi)的開(kāi)源應(yīng)用程序框架,它能幫你不用懂得復(fù)雜的 HTML,CSS 等前端技術(shù)就能快速做出來(lái)一個(gè)炫酷的 Web 頁(yè)面。Streamlit 是一個(gè)用于機(jī)器學(xué)習(xí)、數(shù)據(jù)可視化的 Python 框架,用極短的時(shí)間快速生成一個(gè)基于 Web 的 GUI。當(dāng)然,你也可以將其用于給自己的 Python 腳本創(chuàng)建前端展示頁(yè)面,也是一個(gè)不錯(cuò)的選擇。


二、準(zhǔn)備數(shù)據(jù)
關(guān)鍵字搜索【情人節(jié)禮物 女友 2022】,用第三方采集軟件爬取數(shù)據(jù) 2500+ 條,準(zhǔn)備數(shù)據(jù)如下:



三、分析目的
通過(guò)禮品類別、品牌、和價(jià)格區(qū)間進(jìn)行篩選聯(lián)動(dòng)
① 禮品類別(大類)銷量對(duì)比情況
② 禮品價(jià)格區(qū)間占比情況
③ 各禮品小類的銷量對(duì)比(和大類進(jìn)行聯(lián)動(dòng))
④ 禮品類別的價(jià)格分布
⑤ 品牌禮品的 Top 10 推薦



四、代碼思路
4.1 導(dǎo)入相關(guān)包
import pandas as pd
import plotly.express as px
import streamlit as st
import plotly.figure_factory as ff
import plotly as py
import plotly.graph_objs as go
# 設(shè)置網(wǎng)頁(yè)
st.set_page_config(page_title="數(shù)據(jù)大屏", page_icon=":bar_chart:", layout="wide")
st.balloons()
4.2 讀取數(shù)據(jù)
# 讀取數(shù)據(jù)
@st.cache
def get_data_from_excel():
df = pd.read_excel(
io="data.xlsx",
engine="openpyxl",
sheet_name="data"
)
return df
df = get_data_from_excel()
4.3 設(shè)計(jì)左側(cè)邊欄和標(biāo)題
# 側(cè)邊欄
st.sidebar.header("請(qǐng)?jiān)谶@里篩選:")
category = st.sidebar.multiselect(
"禮物類別:",
options=df["禮品類別"].unique(),
default=df["禮品類別"].unique()
)
brand = st.sidebar.multiselect(
"選擇品牌:",
options=df["品牌"].unique(),
default=df["品牌"].unique(),
)
price = st.sidebar.multiselect(
"價(jià)格區(qū)間:",
options=df["價(jià)格區(qū)間"].unique(),
default=df["價(jià)格區(qū)間"].unique()
)
df_selection = df.query(
"禮品類別 == @category & 品牌 == @brand & 價(jià)格區(qū)間 == @price"
)
# 主頁(yè)面標(biāo)題
st.title(":bar_chart: 情人節(jié)看看大家都送什么禮物")
st.markdown("##")
4.4 畫可視化圖
# 橫向條形圖:各類別禮品銷量
sales_by_product_line = (
df_selection.groupby(by=["禮品類別"]).sum()[["銷量"]]
)
fig_product_sales = px.bar(
sales_by_product_line,
x="銷量",
y=sales_by_product_line.index,
orientation="h",
title="<b>各類別禮品品銷量</b>"
)
fig_product_sales.update_layout(
plot_bgcolor="rgba(0,0,0,0)",
xaxis=(dict(showgrid=False))
)

從禮品類別來(lái)看,送美妝護(hù)膚類的穩(wěn)居第一,看來(lái)情人節(jié)口紅必不可少呀;排名第二的是箱包皮具類,看來(lái)送包包也是也非常不錯(cuò)的選擇呢。
# 圓環(huán)圖:禮物價(jià)格區(qū)間占比
las = df_selection.groupby(df_selection['價(jià)格區(qū)間']).size()
las.sort_values(ascending=True,inplace=True)
layout = go.Layout(
title = '<b>禮品價(jià)格區(qū)間占比</b>',
barmode='stack'
)
fig_price_sales = go.Figure(data=[go.Pie(labels=las.index, hole = 0.7,values=las.values,hoverinfo = "label + percent")],layout=layout)
fig_price_sales.update_layout(
xaxis=dict(tickmode="linear"),
plot_bgcolor="rgba(0,0,0,0)",
yaxis=(dict(showgrid=False)),
)
# 分隔符
st.markdown("""---""")

禮品價(jià)格想必是大家最關(guān)心的了吧,從占比來(lái)看近 50% 的禮品價(jià)格都在 100~500 元之間吶,100 元以下的 6%,價(jià)格區(qū)間占比最小;再看看 2000 元以上的禮品,占比 15%,這是真愛(ài)呀。
# TOP 10 銷量最高品牌
sales_by_brand = df_selection.groupby(by=["品牌"])
brand_dic = {i:j['銷量'].sum() for i,j in sales_by_brand}
brand_dic = sorted(brand_dic.items(), key = lambda kv:(kv[1], kv[0]),reverse=True)
ins = []
val = []
for i, j in brand_dic[:10]:
ins.append(i.split()[0])
val.append(j)
sales_by_brand = px.bar(
x=ins,
y=val,
title="<b>TOP 10 銷量最高品牌</b>",
)
sales_by_brand.update_layout(
xaxis=dict(tickmode="linear"),
plot_bgcolor="rgba(0,0,0,0)",
yaxis=(dict(showgrid=False)),
)

上面結(jié)果是按照所有類別進(jìn)行分析的,當(dāng)然你也可以按照自己喜歡的類別,查看品牌銷量前 10。
# 柱狀圖:各詳細(xì)類別禮品銷量對(duì)比
sales_by_goods = df_selection.groupby(by=["小類"]).sum()[["銷量"]]
sales_by_goods = px.bar(
sales_by_goods,
x=sales_by_goods.index,
y="銷量",
title="<b>詳細(xì)類別產(chǎn)品的銷量</b>",
)
sales_by_goods.update_layout(
xaxis=dict(tickmode="linear"),
plot_bgcolor="rgba(0,0,0,0)",
yaxis=(dict(showgrid=False)),
)

這里選擇【美妝護(hù)膚】這個(gè)類別,分析各小類的銷量對(duì)比,原來(lái)第一的是眼霜和爽膚水,第二的是口紅。想必這是小姐姐的最愛(ài)吧。
# 箱線圖:各類別禮品的價(jià)格分布
fig = px.box(df_selection, x="禮品類別", y="價(jià)格",color="禮品類別",
title="<b>各類別禮品的價(jià)格分布</b>")
fig.update_layout(
xaxis=dict(tickmode="linear"),
plot_bgcolor="rgba(0,0,0,0)",
yaxis=(dict(showgrid=False)),
)

價(jià)格區(qū)間篩選了 1000 元以下的禮品,從結(jié)果來(lái)看,鐘表的價(jià)格最高,大部分都在 500 元以上,好像找到了鐘表銷量最低的原因吶;要說(shuō)性價(jià)比,還是創(chuàng)意禮品、包包、美妝護(hù)膚,中位數(shù)趨于 200~300 之間。
# 將圖形顯示到前端頁(yè)面
left_column, right_column,r = st.columns(3)
right_column.plotly_chart(fig_price_sales, use_container_width=True)
left_column.plotly_chart(fig_product_sales, use_container_width=True)
r.plotly_chart(sales_by_brand, use_container_width=True)
st.markdown("""---""")
left, right = st.columns(2)
left.plotly_chart(sales_by_goods, use_container_width=True)
right.plotly_chart(fig, use_container_width=True)
# 隱藏streamlit默認(rèn)格式信息
hide_st_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
</style>
"""
st.markdown(hide_st_style, unsafe_allow_html=True)
streamlit run demo.py
最后運(yùn)行上面命令,這樣一個(gè)關(guān)于情人節(jié)的數(shù)據(jù)可視化看板,就搭建完成啦!
同時(shí),我也在 B 站發(fā)布了本期內(nèi)容的視頻,歡迎三連呀!
其實(shí)送禮物這事兒,說(shuō)難也不難,但也不是一件簡(jiǎn)單的事兒~送對(duì)了感情升溫,送錯(cuò)了讓你恢復(fù)單身!
推薦閱讀
您看此文用 ![]()
分
![]()
秒,轉(zhuǎn)發(fā)只需1秒哦~

分
秒,轉(zhuǎn)發(fā)只需1秒哦~