自己百度,我没找到最新的定义
python中一个特别厉害的统计画图模块,和seaborn类似,但是这个模块专门用于统计画图
见我上一篇博客,记得点赞哟
现在在服务器上有一堆用户操作机器产生的json文件,这些json文件里面含有一些关键的信息,我们需要将这些信息提取出来,并用图表的形式,给用户一个直观的感受。数据的形式如下:
{
"datatime": "2018-12-12-07:25:34",
"name": "张三",
"No": "001",
"ID": "222222199808080808",
"course": "JJ/L6",
"detail": [
["操作明细", "得分情况"],
["操作明细", "得分情况"],
["操作明细", "得分情况"]
],
"score": 81,
"其余必要信息,乙方可以自己考虑": "xxx"
}
我的目的是根据时间的先后顺序,对用户产生的操作得分画折线图,一个用户画一张图,用户有几种练习就画几条折线,废话不多说,直接撸代码
from PyQt5 import QtCore
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
from pyecharts import Line
import json
import shutil
import os
import re
from ftplib import FTP
先介绍一些这些包的作用,上面几个关于PYQT的是用来生成浏览器的,浏览器可以显示html文档,下面是系统操作需要的一些包,最后那个FTP是用来下载文件的
class Get_User_Drawing:
#实例化参数并和FTP对象,IP,username和psd属于商业机密,所以用星号代替
def __init__(self,ID,ip="*********", username="********", password="*********"):
self.ip = ip
self.username = username
self.pwd = password
self.ftp = FTP(self.ip)
self.ftp.login(self.username,self.pwd)
self.ID = ID
#这个方法是用来下载文件的,通过指定文件名字就可以从服务器下载对应的文件
def down_file_by_name(self,file_name):
bufsize = 1024 # 设置缓冲器大小
fp = open(file_name, 'wb')
self.ftp.retrbinary('RETR %s' % file_name, fp.write, bufsize)
fp.close()
#这个方法是用来获取需要下载的文件名称,并按照练习的种类和时间的先后顺序归类并排序
def get_file(self):
pattern = re.compile("[a-z]{6}_" + self.ID + "_JJ_L.+")#正则匹配的模式
list = self.ftp.nlst()#获取服务器文件列表
prc_type_list = set()#set()可以对练习种类去重
file_list = []#获取对应ID所有的文件
for item in list:
r = re.findall(pattern, item)
if r:
file_list.append(r[0])
prc_type = r[0][14:16]
prc_type_list.add(prc_type) # 找对应ID下所有的练习
file_download = []#获取需要下载的文件,按照时间先后顺序排序
for item_prc in prc_type_list:
pattern = re.compile("[a-z]{6}_"+self.ID+"_JJ_"+str(item_prc)+".+")
time_list = []
for file_item in file_list:
if re.findall(pattern, file_item):
time_ = re.findall(pattern, file_item)[0][17:-5]
time_list.append(int(time_))
time_list = sorted(time_list)
file_download.append([item_prc, time_list])
file_download2 = []#拼接下载文件列表并返回
for item in file_download:
temp = "record_"+self.ID+"_JJ_"+item[0]+"_"
temp1 = []
for time_temp in item[1]:
file = temp + str(time_temp) + ".json"
temp1.append(file)
file_download2.append(temp1)
return file_download2
#下载对应的文件,在本地创建对应的目录,将下载的文件全部移进这个目录中
def down_practice_file_by_ID(self):
path = os.path.abspath(os.curdir)+"\\"+str(self.ID)
if os.path.isdir(path):
pass
else:
os.mkdir(path)
file_list = self.get_file()
for item in file_list:
for file_name in item:
self.down_file_by_name(file_name)
try:
shutil.move(file_name,path)#尝试将文件移动到对应的目录中
except BaseException:
os.remove(path+"\\"+file_name)#如果对应目录下有文件,将原文件删除并将下载的文件移入,保证文件是最新的
shutil.move(file_name,path)
#解析下载好的文件,获取数据并返回一个字典
def get_practice_file_info(self):
self.down_practice_file_by_ID()
path = str(os.path.abspath(os.curdir)) + "\\" + str(self.ID) + "\\"
if os.path.isdir(path):
pass
else:
print("文件未下载!")
list = self.get_file()
info = {}#信息的字典,练习种类作为键,值是一个列表,包含用户所有的信息
for item in list:
prc = item[0][14:16]
info1 = []
for file_name in item:
info2 = []
json_file = path+file_name
with open(json_file, 'r', encoding='utf8') as f:
data = json.load(f)
info2.append(data["name"])
info2.append(data["No"])
info2.append(data["course"][0:2])
info2.append(data["score"])
info1.append(info2)
info[prc] = info1
return info
#对info中的信息绘图
def draw(self):
info = self.get_practice_file_info()
path = str(os.path.abspath(os.curdir)) + "\\" + str(self.ID)
file_name = str(self.ID)+".html"#绘图需要的html文件
if info:#如果info不为空则绘图
title = info[list(info.keys())[0]][0][0] + "_" + info[list(info.keys())[0]][0][1]#图的标题
subtitle = info[list(info.keys())[0]][0][2]#图的子标题
line = Line(title, subtitle, subtitle_color="green", background_color='#f8f8ff',width=830,height=470)#创建折线对象,对应参数指定
for key in info.keys():#获取信息
value = []
for val in info[key]:
value.append(val[3])
line.add(key, [i for i in range(len(value))], value, mark_point=["max", "min"], mark_line=["average"], )#添加折线
line.render(file_name)#生成html文件
#将生成的文件移入用户文件夹,如果有则删除并移入,保证文件是最新的
try:
shutil.move(file_name, path)
except BaseException:
os.remove(path+"\\"+file_name)
shutil.move(file_name, path)
else:
print("用户未练习!")
#这个类是用来创建浏览器并显示html文件
class MainWindow(QMainWindow):
def __init__(self,id):
super(QMainWindow,self).__init__()
self.get_user_draw = Get_User_Drawing(id)
self.draw = self.get_user_draw.draw()#生成html文件
self.setGeometry(400,300,851,501)#前两个参数是到左上角的距离,后两个参数是浏览器的大小
self.browser = QWebEngineView()
file_str = os.path.abspath(os.curdir)+"\\"+str(id)+"\\"+str(id) + ".html"
file_name = ""
for item in file_str.split("\\"):
file_name+=item+"/"
file_name = file_name[:-1]#将\换成/,不然文件找不到
self.browser.load(QUrl(file_name))
self.setCentralWidget(self.browser)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)#生成无边框的浏览器,伪造图片的效果
if name==“main”:
app = QApplication(sys.argv)
win = MainWindow(“001”)
win.show()
sys.exit(app.exec_())
![在这里插入图片描述](https://img-blog.csdnimg.cn/2018122910473875.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNTM4OTM4,size_16,color_FFFFFF,t_70)