Python制作数据可视化大屏

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972

   个人介绍: 研一|统计学|干货分享
         擅长Python、Matlab、R等主流编程软件
         累计十余项国家级比赛奖项,参与研究经费10w、40w级横向

该篇文章利用Python对某学校2021级人工智能学院食堂情况就餐消费制作可视化大屏,包括六大核心模块:学生交易金额;交易成功率;学生交易类型情况;学生消费位置情况;学生交易月度预测;学生交易余额情况。各模块以不同类型图展示,其中学生交易月度预测模块嵌入自动寻优的ARIMA算法。


文末附完整代码!望关注支持!

1 加载相关包并读取数据

  运行程序:

import pandas as pd
import pmdarima as pm
from pandas import DataFrame
import warnings
warnings.filterwarnings('ignore')
from pyecharts import options as opts
from pyecharts.charts import Bar,Gauge,Pie,Page,Funnel
from bs4 import BeautifulSoup
##预测
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
from pyecharts.charts import Line
data = pd.read_excel(r'D:\\驾驶舱\\2021级人工智能食堂就餐消费明细.xlsx',sheet_name=0)

2 学生金额交易情况柱状图模块

  运行程序:

score_list =data['交易金额']
print(score_list)
# 指定多个区间
bins = [-100, 0, 10,20,60, 100, 200]
score_cut = pd.cut(score_list, bins)
print(type(score_cut)) # <class 'pandas.core.arrays.categorical.Categorical'>
print(score_cut)
print(pd.value_counts(score_cut)) # 统计每个区间人数
bar1=DataFrame(pd.value_counts(score_cut))
# 条形图  
def bar():
    #柱状图
    cate = ['充值', '0-10元', '10-20元', '20-60元', '60-100元', '大于100元']
    c = (
    Bar()
    .add_xaxis(cate)
    .add_yaxis("交易人次:人",[84, 16659, 8462, 852, 14, 6])
    .set_global_opts(
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
        title_opts=opts.TitleOpts(title="学生交易金额情况")
    )
    )
    return c

  运行结果:

交易金额
(0, 10]       16659
(10, 20]       8462
(20, 60]        852
(-100, 0]        84
(60, 100]        14
(100, 200]        6
Name: count, dtype: int64

3 标题模块

  运行程序:

def tab0(name,color): #标题
    c = (Pie().
        set_global_opts(
        title_opts=opts.TitleOpts(title=name,pos_left='center',pos_top='center',
                                title_textstyle_opts=opts.TextStyleOpts(color=color,font_size=20))))
    return c


def tab1(name,color): #标题
    c = (Pie().
        set_global_opts(
        title_opts=opts.TitleOpts(title=name,pos_left='center',pos_top='center',
                                title_textstyle_opts=opts.TextStyleOpts(color=color,font_size=25))))
    return c
    
def tab2(name,color): #标题
    c = (Pie().
        set_global_opts(
        title_opts=opts.TitleOpts(title=name,pos_left='center',pos_top='center',
                                title_textstyle_opts=opts.TextStyleOpts(color=color,font_size=17.5))))
    return c

4 交易类型成功率仪表板模块

  运行程序:

def gau():#仪表图
    c = (
        Gauge(init_opts=opts.InitOpts(width="400px", height="400px"))
            .add(series_name="交易成功率", data_pair=[["", 100]])
            .set_global_opts(
            legend_opts=opts.LegendOpts(is_show=False),
            tooltip_opts=opts.TooltipOpts(is_show=True, formatter="{a} <br/>{b} : {c}%"),
            
        )
        .set_global_opts(
        title_opts=opts.TitleOpts(title="交易成功率"),
        legend_opts=opts.LegendOpts(is_show=False),
    )
            #.render("gauge.html")
    )
    return c

5 交易类型占比圆环图模块

  运行程序:

def gau():#仪表图
    c = (
        Gauge(init_opts=opts.InitOpts(width="400px", height="400px"))
            .add(series_name="交易成功率", data_pair=[["", 100]])
            .set_global_opts(
            legend_opts=opts.LegendOpts(is_show=False),
            tooltip_opts=opts.TooltipOpts(is_show=True, formatter="{a} <br/>{b} : {c}%"),
            
        )
        .set_global_opts(
        title_opts=opts.TitleOpts(title="交易成功率"),
        legend_opts=opts.LegendOpts(is_show=False),
    )
            #.render("gauge.html")
    )
    return c

6 学生消费位置情况金字塔图模块

  运行程序:


data1=data
data1['终端名称']=data1['终端名称'].apply(lambda x:x[0:4]).tolist()
df2=pd.DataFrame(data1.groupby('终端名称').count())

df2.iloc[:,0]
def funnel():
    cate = ['学二食堂', '管理中心', '蜜雪冰城', '食堂1层', '食堂2层','食堂3层']
    data = [731, 83, 40, 18916, 5855,452]
    c = Funnel()
    c.add("用户数", [list(z) for z in zip(cate, data)], 
               sort_='ascending',
               label_opts=opts.LabelOpts(position="inside"))
    c.set_global_opts(title_opts=opts.TitleOpts(title=""))


    return c

7 学生交易月度预测值折线图模块

  运行程序:


data1=data
data1['终端名称']=data1['终端名称'].apply(lambda x:x[0:4]).tolist()
df2=pd.DataFrame(data1.groupby('终端名称').count())

df2.iloc[:,0]
def funnel():
    cate = ['学二食堂', '管理中心', '蜜雪冰城', '食堂1层', '食堂2层','食堂3层']
    data = [731, 83, 40, 18916, 5855,452]
    c = Funnel()
    c.add("用户数", [list(z) for z in zip(cate, data)], 
               sort_='ascending',
               label_opts=opts.LabelOpts(position="inside"))
    c.set_global_opts(title_opts=opts.TitleOpts(title=""))


    return c

  运行结果:

 ARIMA(0,0,0)(0,0,0)[0]             : AIC=340.998, Time=0.01 sec
 ARIMA(0,0,1)(0,0,0)[0]             : AIC=inf, Time=0.02 sec
 ARIMA(0,0,2)(0,0,0)[0]             : AIC=inf, Time=0.05 sec
 ARIMA(0,0,3)(0,0,0)[0]             : AIC=341.289, Time=0.02 sec
 ARIMA(0,0,4)(0,0,0)[0]             : AIC=333.644, Time=0.07 sec
 ARIMA(0,0,5)(0,0,0)[0]             : AIC=333.412, Time=0.09 sec
 ARIMA(1,0,0)(0,0,0)[0]             : AIC=331.546, Time=0.01 sec
 ARIMA(1,0,1)(0,0,0)[0]             : AIC=331.817, Time=0.02 sec
 ARIMA(1,0,2)(0,0,0)[0]             : AIC=inf, Time=0.07 sec
 ARIMA(1,0,3)(0,0,0)[0]             : AIC=334.645, Time=0.04 sec
 ARIMA(1,0,4)(0,0,0)[0]             : AIC=inf, Time=0.05 sec
 ARIMA(2,0,0)(0,0,0)[0]             : AIC=333.891, Time=0.01 sec
 ARIMA(2,0,1)(0,0,0)[0]             : AIC=inf, Time=0.05 sec
 ARIMA(2,0,2)(0,0,0)[0]             : AIC=inf, Time=0.17 sec
 ARIMA(2,0,3)(0,0,0)[0]             : AIC=inf, Time=0.11 sec
 ARIMA(3,0,0)(0,0,0)[0]             : AIC=334.395, Time=0.02 sec
 ARIMA(3,0,1)(0,0,0)[0]             : AIC=333.921, Time=0.04 sec
 ARIMA(3,0,2)(0,0,0)[0]             : AIC=inf, Time=0.11 sec
 ARIMA(4,0,0)(0,0,0)[0]             : AIC=336.171, Time=0.02 sec
 ARIMA(4,0,1)(0,0,0)[0]             : AIC=335.691, Time=0.05 sec
 ARIMA(5,0,0)(0,0,0)[0]             : AIC=inf, Time=0.05 sec

Best model:  ARIMA(1,0,0)(0,0,0)[0]          
Total fit time: 1.094 seconds
2021-12-31    10154.394624
2022-01-31     7244.767300
2022-02-28     5168.860890
Freq: M, dtype: float64

8 学生交易余额情况柱状图模块

  运行程序:

##条形图
##条形图数据
score_list1 =data['可用余额(交易后)']
print(score_list1)
# 指定多个区间
bins1 = [-1000,0,50, 100,200,500, 1000]
score_cut1 = pd.cut(score_list1, bins1)
print(type(score_cut1)) # <class 'pandas.core.arrays.categorical.Categorical'>
print(score_cut1)
print(pd.value_counts(score_cut1)) # 统计每个区间人数
bar2=DataFrame(pd.value_counts(score_cut1))
def bar2():
    #柱状图
    cate = ['待充值', '0-50元', '50-100元', '100-200元', '200-500元', '大于500元']
    c = (
    Bar()
    .add_xaxis(cate)
    .add_yaxis("余额状态次数:人次",[180, 10322, 7223, 5236, 2595, 521])
    .set_global_opts(
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
        title_opts=opts.TitleOpts(title="学生交易余额情况")
    )
    )
    return c

  运行结果:

0          0.00
1          0.00
2          0.00
3         94.80
4         44.60
 
26072    204.41
26073     90.36
26074     22.10
26075    367.50
26076      2.02
Name: 可用余额(交易后), Length: 26077, dtype: float64
<class 'pandas.core.series.Series'>
0        (-1000, 0]
1        (-1000, 0]
2        (-1000, 0]
3         (50, 100]
4           (0, 50]
   
26072    (200, 500]
26073     (50, 100]
26074       (0, 50]
26075    (200, 500]
26076       (0, 50]
Name: 可用余额(交易后), Length: 26077, dtype: category
Categories (6, interval[int64, right]): [(-1000, 0] < (0, 50] < (50, 100] < (100, 200] < (200, 500] <
                                         (500, 1000]]
可用余额(交易后)
(0, 50]        10322
(50, 100]       7223
(100, 200]      5236
(200, 500]      2595
(500, 1000]      521
(-1000, 0]       180
Name: count, dtype: int64

9 模块拼接保存

  运行程序:

page = Page() 
page.add(
         tab0("2021级","#2CB34A"), 
         bar(),
         tab1("人工智能学院食堂就餐消费驾驶舱","#2CB34A"),
         gau(),
         radius(),
         funnel(),
         line(),
         bar2(),
         tab2("学生消费位置情况","black")
         )
page.render("D:\\驾驶舱\\驾驶舱3.html")

  运行结果:

10 页面布局优化

  运行程序:

##对页面布局
#divs[0][“style”] = “width:10%;height:10%;position:absolute;top:0;left:2%;” 即是我们对Part0的宽度、高度、位置、上边距、左边距的定义,这里我们用百分比以达到屏幕自适应的效果

with open("D:\\驾驶舱\\驾驶舱3.html", "r+", encoding='utf-8') as html:
    html_bf = BeautifulSoup(html, 'lxml')
    divs = html_bf.select('.chart-container')
    divs[0]["style"] = "width:10%;height:10%;position:absolute;top:0;left:2%;"
    divs[1]["style"] = "width:40%;height:40%;position:absolute;top:12%;left:0;"  
    divs[2]["style"] = "width:35%;height:10%;position:absolute;top:2%;left:30%;"
    divs[3]["style"] = "width:40%;height:40%;position:absolute;top:10%;left:28%;"
    divs[4]["style"] = "width:40%;height:35%;position:absolute;top:12%;left:55%;"
    divs[5]["style"] = "width:30%;height:35%;position:absolute;top:60%;left:2%;"
    divs[6]["style"] = "width:40%;height:50%;position:absolute;top:50%;left:30%;"
    divs[7]["style"] = "width:35%;height:40%;position:absolute;top:50%;left:65%;"
    divs[8]["style"] = "width:10%;height:10%;position:absolute;top:47%;left:0%;"
    body = html_bf.find("body")
    body["style"] = "background-image:url(背景1.jpg)"  # 更换背景
    html_new = str(html_bf)
    html.seek(0, 0)
    html.truncate()
    html.write(html_new)

  运行结果:

11 完整代码

# -*- coding: utf-8 -*-
"""
Created on Thu Dec 15 08:36:32 2022


"""
import pandas as pd
import pmdarima as pm
from pandas import DataFrame
import warnings
warnings.filterwarnings('ignore')
from pyecharts import options as opts
from pyecharts.charts import Bar,Gauge,Pie,Page,Funnel
from bs4 import BeautifulSoup
##预测
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
from pyecharts.charts import Line

data = pd.read_excel(r'D:\\代做项目\\驾驶舱\\2021级人工智能食堂就餐消费明细.xlsx',sheet_name=0)
##共26077条数据
##图1数据

score_list =data['交易金额']
print(score_list)
# 指定多个区间
bins = [-100, 0, 10,20,60, 100, 200]
score_cut = pd.cut(score_list, bins)
print(type(score_cut)) # <class 'pandas.core.arrays.categorical.Categorical'>
print(score_cut)
print(pd.value_counts(score_cut)) # 统计每个区间人数
bar1=DataFrame(pd.value_counts(score_cut))
# 条形图  
def bar():
    #柱状图
    cate = ['充值', '0-10元', '10-20元', '20-60元', '60-100元', '大于100元']
    c = (
    Bar()
    .add_xaxis(cate)
    .add_yaxis("交易人次:人",[84, 16659, 8462, 852, 14, 6])
    .set_global_opts(
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
        title_opts=opts.TitleOpts(title="学生交易金额情况")
    )
    )
    return c


def tab0(name,color): #标题
    c = (Pie().
        set_global_opts(
        title_opts=opts.TitleOpts(title=name,pos_left='center',pos_top='center',
                                title_textstyle_opts=opts.TextStyleOpts(color=color,font_size=20))))
    return c


def tab1(name,color): #标题
    c = (Pie().
        set_global_opts(
        title_opts=opts.TitleOpts(title=name,pos_left='center',pos_top='center',
                                title_textstyle_opts=opts.TextStyleOpts(color=color,font_size=25))))
    return c

def tab2(name,color): #标题
    c = (Pie().
        set_global_opts(
        title_opts=opts.TitleOpts(title=name,pos_left='center',pos_top='center',
                                title_textstyle_opts=opts.TextStyleOpts(color=color,font_size=17.5))))
    return c


def gau():#仪表图
    c = (
        Gauge(init_opts=opts.InitOpts(width="400px", height="400px"))
            .add(series_name="交易成功率", data_pair=[["", 100]])
            .set_global_opts(
            legend_opts=opts.LegendOpts(is_show=False),
            tooltip_opts=opts.TooltipOpts(is_show=True, formatter="{a} <br/>{b} : {c}%"),
            
        )
        .set_global_opts(
        title_opts=opts.TitleOpts(title="交易成功率"),
        legend_opts=opts.LegendOpts(is_show=False),
    )
            #.render("gauge.html")
    )
    return c

df1=pd.DataFrame(data.groupby('交易描述').count())
df1.iloc[:,0]
def radius():
    cate = ['IC卡消费', 'dmt', '业务操作', '支付码消费']
    data = [11584, 2, 81,14410]
    c = (
    Pie()
    .add(
        "",
        [
            list(z)
            for z in zip(
                cate,
                data,
            )
        ],
        radius=["30%", "75%"],
        rosetype="radius"
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="交易类型占比"),
        legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical"),
    )
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
)
    return c



data1=data
data1['终端名称']=data1['终端名称'].apply(lambda x:x[0:4]).tolist()
df2=pd.DataFrame(data1.groupby('终端名称').count())

df2.iloc[:,0]
def funnel():
    cate = ['学二食堂', '管理中心', '蜜雪冰城', '食堂1层', '食堂2层','食堂3层']
    data = [731, 83, 40, 18916, 5855,452]
    c = Funnel()
    c.add("用户数", [list(z) for z in zip(cate, data)], 
               sort_='ascending',
               label_opts=opts.LabelOpts(position="inside"))
    c.set_global_opts(title_opts=opts.TitleOpts(title=""))


    return c

##预测图
data1=data
data1['记账日期']=data1['记账日期'].astype('str')
data1['记账日期']=data1['记账日期'].apply(lambda x:x[0:6]).tolist()
data2=data1[['记账日期','交易金额']]
data2=pd.DataFrame(data2.groupby('记账日期').sum())
data3=data2.sort_index(axis=1)##根据索引列排序
#data3.to_excel('D:\\代做项目\\驾驶舱\\聚合数据.xlsx',index=True)#将数据文件中未存在的月份赋值为0
data4=pd.read_excel(r'D:\\代做项目\\驾驶舱\\聚合数据.xlsx',sheet_name=0)
data4.set_index('记账日期',inplace = True)

#plt.figure(figsize=(12,8))
#data4.plot()
adfuller(data4['交易金额'])
#非平稳差分
dta=pd.Series(data4['交易金额'])
dta.index = pd.Index(sm.tsa.datetools.dates_from_range('2020m9',length=15))


model = pm.auto_arima(dta, start_p=1, start_q=1,
                           max_p=8, max_q=8, m=1,
                           start_P=0, seasonal=False,
                           max_d=3, trace=True,
                           information_criterion='aic',
                           error_action='ignore',
                           suppress_warnings=True,
                           stepwise=False)
forecast = model.predict(3)#预测未来3个月的数据
print(forecast)
#为绘图的连续性把2090的值添加为PredicValue第一个元素


ser_df1=pd.DataFrame(dta).reset_index()
ser_df1.columns = ['记账日期','交易金额']
ser_df2=pd.DataFrame(forecast).reset_index()
ser_df2.columns = ['记账日期','交易金额']
ser_df3=pd.concat([ser_df1,ser_df2])
ser_df3['记账日期']=ser_df3['记账日期'].astype('str')
ser_df3['记账日期']=ser_df3['记账日期'].apply(lambda x:x[0:7]).tolist()
ser_df3['交易金额']=round(ser_df3['交易金额'],2)
ser_df4=[None,None,None,None,None,None,None,None,None,None,None,None,None,None,None]+list(ser_df3.交易金额)[15:18]



def line():
    c = (
        Line()
        .add_xaxis(list(ser_df3.记账日期))
        .add_yaxis('实际值',list(ser_df3.交易金额)[:15], is_smooth=True)
        .add_yaxis("预测值",ser_df4, is_smooth=True)
        .set_global_opts(title_opts=opts.TitleOpts(title="学生交易月度预测值"))
    )
    return c


##条形图
##条形图数据
score_list1 =data['可用余额(交易后)']
print(score_list1)
# 指定多个区间
bins1 = [-1000,0,50, 100,200,500, 1000]
score_cut1 = pd.cut(score_list1, bins1)
print(type(score_cut1)) # <class 'pandas.core.arrays.categorical.Categorical'>
print(score_cut1)
print(pd.value_counts(score_cut1)) # 统计每个区间人数
bar2=DataFrame(pd.value_counts(score_cut1))
def bar2():
    #柱状图
    cate = ['待充值', '0-50元', '50-100元', '100-200元', '200-500元', '大于500元']
    c = (
    Bar()
    .add_xaxis(cate)
    .add_yaxis("余额状态次数:人次",[180, 10322, 7223, 5236, 2595, 521])
    .set_global_opts(
        xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
        title_opts=opts.TitleOpts(title="学生交易余额情况")
    )
    )
    return c



page = Page() 
page.add(
         tab0("2021级","#2CB34A"), 
         bar(),
         tab1("人工智能学院食堂就餐消费驾驶舱","#2CB34A"),
         gau(),
         radius(),
         funnel(),
         line(),
         bar2(),
         tab2("学生消费位置情况","black")
         )
page.render("D:\\代做项目\\驾驶舱\\驾驶舱3.html")

##对页面布局
#divs[0][“style”] = “width:10%;height:10%;position:absolute;top:0;left:2%;” 即是我们对Part0的宽度、高度、位置、上边距、左边距的定义,这里我们用百分比以达到屏幕自适应的效果

with open("D:\\代做项目\\驾驶舱\\驾驶舱3.html", "r+", encoding='utf-8') as html:
    html_bf = BeautifulSoup(html, 'lxml')
    divs = html_bf.select('.chart-container')
    divs[0]["style"] = "width:10%;height:10%;position:absolute;top:0;left:2%;"
    divs[1]["style"] = "width:40%;height:40%;position:absolute;top:12%;left:0;"  
    divs[2]["style"] = "width:35%;height:10%;position:absolute;top:2%;left:30%;"
    divs[3]["style"] = "width:40%;height:40%;position:absolute;top:10%;left:28%;"
    divs[4]["style"] = "width:40%;height:35%;position:absolute;top:12%;left:55%;"
    divs[5]["style"] = "width:30%;height:35%;position:absolute;top:60%;left:2%;"
    divs[6]["style"] = "width:40%;height:50%;position:absolute;top:50%;left:30%;"
    divs[7]["style"] = "width:35%;height:40%;position:absolute;top:50%;left:65%;"
    divs[8]["style"] = "width:10%;height:10%;position:absolute;top:47%;left:0%;"
    body = html_bf.find("body")
    body["style"] = "background-image:url(背景1.jpg)"  # 更换背景
    html_new = str(html_bf)
    html.seek(0, 0)
    html.truncate()
    html.write(html_new)
  • 15
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值