#调用相关模块
from pyecharts import options as opts
from pyecharts.charts import Bar, Page, Pie,Line
from pyecharts.components import Table
from pyecharts.globals import ThemeType
import pandas as pd
#封装一个sort_order来提取需要的数据
class sort_order():
colors = ["#5793f3", "#d14a61", "#675bba","pink"]
Time = []
per_sum = [] #每天五大类时长 嵌套列表
sum_list = [] #过渡列表
part_sums = [] #每天各项活动时长求和 嵌套列表
sum_activity = None #各项操作总时长
def __init__(self):
'''
重写初始化方法,封装成员方法
'''
self.data = pd.read_excel(r"D:\myLife\myLife(2).xlsx",sheet_name=1)
self.values = self.data.groupby("日期")
self.df0 = self.values.groups.keys()
self.operation = self.data["操作"].unique()
value = self.data.groupby("操作")
self.operation_name = list(value.groups.keys())
self.every_time()
self.every_sum()
self.per_sort_sum(self.data)
self.get_group_values()
self.sum_all()
def every_sum(self):
'''
获取每天五大类时长
'''
for j in self.df0:
i = self.values.get_group(j)
val = self.per_sort_sum(i)
self.per_sum.append(val)
def every_time(self):
'''
获取时间戳
'''
for i in list(self.df0):
self.Time.append(i.strftime("%Y年-%m月-%d日"))
def sort_sum(self,i):
'''
对传入的i进行求和,并转成列表
'''
dts = i["时长"].sum()
return dts.tolist()
def per_sort_sum(self,i):
'''
根据相关操作名称进行分组,并求和
'''
if len(i) > 100:
i = self.data
a = i.query("操作=='阅读'|操作=='上课'|操作=='写作'|操作=='备课'|操作=='实验'|操作=='思考'|操作=='编程'|操作=='记录'")
b = i.query("操作=='拍摄'|操作=='玩手机'|操作=='欣赏'|操作=='购物'")
A = i.query("操作=='睡眠'|操作=='午睡'|操作=='休养'|操作=='吃早餐'|操作=='吃午餐'|操作=='吃晚餐'|操作=='喝水'")
B = i.query("操作=='打球'|操作=='步行'")
C = i.query("操作=='讨论'|操作=='开会'|操作=='网聊'")
list1 = [a,b,A,B,C]
self.list2 = []
for i in list1:
self.list2.append(self.sort_sum(i))
return self.list2
def get_group_values(self):
'''
获取每天各项活动时长
'''
self.part_sums = []
for j in list(self.df0):
dt = self.values.get_group(j)
dts = dt.groupby('操作').sum()
self.part_sums.append(list(dts['时长']))
def sum_all(self):
'''
统计所有操作的总时长
'''
val = self.data.groupby('操作').sum()
self.sum_activity = list(val["时长"])
dt = sort_order()
attr = ["学习", "娱乐", "休息", "运动", "交流"]
# 将每个图 封装到 函数
# 1.柱形图
def bar_datazoom_slider() -> Bar:
c = (Bar()
.add_xaxis(dt.operation_name) #x轴的值
.add_yaxis(series_name="时长总和(min)",y_axis=dt.sum_activity,color=dt.colors[1]) #柱形1的标签,y轴的值,颜色
.set_global_opts(toolbox_opts=opts.ToolboxOpts(is_show=True, #工具箱配置项
pos_top="top",
pos_left="right", #设置工具箱配置项的位置
feature={"saveAsImage": {} , #保存图片工具
"magicType":{"show": True, "type":["line","bar"]}, #转换成折线图和柱形图工具
"dataView": {} }), #数据视图工具
xaxis_opts=opts.AxisOpts(name="活动", #x轴的标签设置
axisline_opts=opts.AxisLineOpts(linestyle_opts=opts.LineStyleOpts(color=dt.colors[1]))), #坐标轴刻度线配置项
yaxis_opts=opts.AxisOpts(name="小时", #y轴的标签设置
axisline_opts=opts.AxisLineOpts(linestyle_opts=opts.LineStyleOpts(color=dt.colors[2])),#坐标轴刻度线配置项
axislabel_opts=opts.LabelOpts(formatter="{value}")), #当前列的数据进行格式化操作 value:表示当前单元格中的值
tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross"),#轴触发触碰到图形显示全部数据 类型为十字准星
title_opts=opts.TitleOpts(title="学生各项活动时长分析"), #设置标题
datazoom_opts=[opts.DataZoomOpts()] #设置滑动轴
))
return c
# # 2.带标记点的折线图
def line_markpoint() -> Line:
c = (
Line()
.add_xaxis(attr)
.add_yaxis("总时长(min)",dt.list2,color=dt.colors[2])
.set_global_opts(toolbox_opts=opts.ToolboxOpts(is_show=True, #工具箱配置项
pos_top="top",
pos_left="right", #设置工具箱配置项的位置
feature={"saveAsImage": {} , #保存图片工具
"magicType":{"show": True, "type":["line","bar"]},#转换成折线图和柱形图工具
"dataView": {} }), #数据视图工具
xaxis_opts=opts.AxisOpts(name="活动", #x轴的标签设置
axisline_opts=opts.AxisLineOpts(linestyle_opts=opts.LineStyleOpts(color=dt.colors[0]))), #坐标轴刻度线配置项
yaxis_opts=opts.AxisOpts(name="小时", #y轴的标签设置
axisline_opts=opts.AxisLineOpts(linestyle_opts=opts.LineStyleOpts(color=dt.colors[3])), #坐标轴刻度线配置项
axislabel_opts=opts.LabelOpts(formatter="{value}")), #当前列的数据进行格式化操作 value:表示当前单元格中的值
tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross"),
title_opts=opts.TitleOpts(title="学生活动时长分析"),
datazoom_opts=[opts.DataZoomOpts()]
))
return c
# 3.饼图
def pie1_rosetype() -> Pie:
c = (
Pie(init_opts=opts.InitOpts(theme=ThemeType.LIGHT,width='1000px',height='600px')) #主题风格
.add("", [list(z) for z in zip(attr,dt.sum_activity)] )
.set_global_opts(title_opts=opts.TitleOpts(title="学生活动时长占比",pos_top="top",pos_left="left"),
legend_opts=opts.LegendOpts(pos_left="right", orient="vertical")) # 设置标题
.set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{d}%'))) # 显示百分比
return c
# #zip函数同时获取两组值,并按照对应的位置组合形成元组,存放到列表里
# #zip 每个元素是 x/df1 两个列表中同位置元素的 tuple,比如('上课',上课对应的时长)
# # list(z) 本质是 list(('上课', 上课对应的时长)),结果是[('上课',上课对应的时长)]
# 4.嵌套饼图
inner_data_pair = [z for z in zip(attr,dt.list2 )]
outer_data_pair = [z for z in zip(attr, dt.sum_activity)]
def pie2_rosetype() -> Pie:
c =(
Pie(init_opts=opts.InitOpts(theme=ThemeType.LIGHT,width='1400px',height='800px'))
.add(
series_name="总时长(min)",
data_pair=inner_data_pair,
radius=[0, "30%"],
label_opts=opts.LabelOpts(position="inner"),
)
.add(
series_name="总时长(min)",
radius=["40%", "55%"],
data_pair=outer_data_pair,
label_opts=opts.LabelOpts(
position="outside",
formatter="{a|{a}}{abg|}\n{hr|}\n {b|{b}: }{c} {per|{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"a": {"color": "#999", "lineHeight": 22, "align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
.set_global_opts(legend_opts=opts.LegendOpts(pos_left="right", orient="vertical"))
.set_series_opts(
tooltip_opts=opts.TooltipOpts(
trigger="item", formatter="{a}
{b}: {c} ({d}%)"
)
))
return c
# #6.表格
def table_base() -> Table:
table = Table()
headers =["Activity summary"]
rows = [
["The sum of the dates"],
[len(dt.df0)],
["Analysis 学习 娱乐 休息 运动 交流 Total duration (小时)"],
[dt.list2],
["上课 步行 吃晚餐 吃午餐 吃早餐 喝水 记录 排泄 睡眠 思考 洗漱 写作 网聊 拍摄 玩手机 阅读 午睡 沏茶做饭 编程 分发 讨论 备课 欣赏 开会 休养 驾车 购物 实验 打球 充值 (小时)"],
[dt.sum_activity]
]
table.add(headers,rows).set_global_opts(
title_opts=opts.ComponentTitleOpts(title="学生活动时长数据视图"))
return table
# #7.page()运行多图
def page_simple_layout():
page = Page(layout=Page.SimplePageLayout)
page.add(
bar_datazoom_slider(),
pie1_rosetype(),
line_markpoint(),
pie2_rosetype(),
table_base())
page.render("人生导航数据分析.html")
#放到主函数执行
#作用:当模块被直接运行时,以下代码块将被运行.当模块是被导入时(从另一个py文件调用模块时),以下代码块不被运行。
if __name__ == "__main__":
page_simple_layout()
print('完成')
这个是文件链接【金山文档】 myLife(2)1,需要的小伙伴可打开下载
想要了解更详细的操作或者是想要绘制其他的图表,请点击下方链接
pyechast的GitHub官方文档