#coding:utf-8 # 导入matplotlib模块并使用Qt5Agg import typing from PyQt5.QtCore import QObject import matplotlib matplotlib.use('Qt5Agg') # 使用 matplotlib中的FigureCanvas (在使用 Qt5 Backends中 FigureCanvas继承自QtWidgets.QWidget) from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * import matplotlib.pyplot as plt import sys import scheme_data import numpy as np import threading import os import build_html plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False # 定义一个可以嵌入到qt的figure class QFigure(QObject): def __init__(self,title:str) -> None: QObject.__init__(self) self.__figure = plt.figure(figsize=(14,7)) self.__canvas = FigureCanvas(self.__figure) self.__ax = self.__figure.add_axes([0.1,0.1,0.8,0.8]) self.__ax.set_title(title) self._title=title def draw(self,x,y,lable:str=None,limit_max:int=None,limit_min:int=None): line,=self.__ax.plot(x,y,) if(lable!=None): line.set_label(lable) self.__ax.legend() if(limit_max!=None): self.__ax.axhline(y=limit_max,color='g',linestyle='--') if(limit_min!=None): self.__ax.axhline(y=limit_min,color='r',linestyle='--') # start, end = self.__ax.get_ylim() # self.__ax.yaxis.set_ticks(np.arange(start, end,(end-start)/20),minor=True) # ticks=self.__ax.yaxis.get_ticklocs() # self.__ax.yaxis.set_ticks(minor=True) # self.__ax.yaxis.set_ticks(ticks) self.__ax.grid(visible=True,which="major",axis="y") self.__canvas.draw() def save(self,path:str,perfix:str): path=os.path.join(path,"pic") if not os.path.exists(path): os.makedirs(path) name=os.path.join(path,perfix+self._title) self.__figure.savefig(name+'.png') def lable(self,lablex,labley): self.__ax.set_ylabel(labley) self.__ax.set_xlabel(lablex) def canvas(self): return self.__canvas # 定义一个任务需要的参数布局 class TParamLayout(QObject): def __init__(self) -> None: QObject.__init__(self) self.__layout=QFormLayout() self.__items=[] def add_item(self,name:str,value:str="",tooltip:str=None): line_edit = QLineEdit() line_edit.setObjectName(value) line_edit.setText(value) line_edit_label = QLabel() line_edit_label.setObjectName(name) line_edit_label.setText(name) line_edit_label.setAlignment(Qt.AlignmentFlag.AlignCenter) if(tooltip!=None): line_edit_label.setToolTip(tooltip) line_edit.setToolTip(tooltip) self.__layout.addRow(line_edit_label,line_edit) self.__items.append((line_edit_label,line_edit)) def item_value(self,name:str): for i in self.__items: if(i[0].text()==name): return i[1].text() return None def values(self): vals=[] for i in self.__items: vals.append((i[0].text(),i[1].text())) return vals def layout(self): return self.__layout class Analysis(QWidget): data_recv_end_signal =pyqtSignal([list,list]) calc_item_end_signal =pyqtSignal([list]) def __init__(self,parent=None): super(Analysis,self).__init__(parent) self.setWindowTitle("检测数据分析") self.calc_item_end_signal.connect(self.calc_item_end_slot) self.data_recv_end_signal.connect(self.data_recv_end_slot) self.__import_but = QPushButton("导入方案",self) self.__import_but.clicked.connect(self.import_but_clicked) self.__import_but.setGeometry(QRect(0,0,100,27)) self.__export_but = QPushButton("导出数据") self.__export_but.clicked.connect(self.export_but_clicked) self.__scroll=QScrollArea(self) self.__scroll.setGeometry(0,30,1230,700) # 设置布局 self.__layout = QFormLayout() self.__layout.addRow(' ',self.__export_but) self.__items=[] def add_item(self,data_dict:dict): data=data_dict["data"] x=data_dict["x"] name=data_dict["name"] max=data_dict["max"] min=data_dict["min"] avg=data_dict["avg"] mid=data_dict["mid"] std=data_dict["std"] limit_max=data_dict["limit_max"] limit_min=data_dict["limit_min"] dat_count=data_dict["dat_count"] y=data_dict["y"] figure = QFigure(name) figure.lable("序号","数值") tplayout=TParamLayout() tplayout.add_item(name+":Max",str(max)) tplayout.add_item(name+":Min",str(min)) tplayout.add_item(name+":Avg",str(avg)) tplayout.add_item(name+":Mid",str(mid)) tplayout.add_item(name+":Std",str(std)) tplayout.add_item(name+":LimitMax",str(limit_max)) tplayout.add_item(name+":LimitMin",str(limit_min)) self.__layout.addRow(figure.canvas(),tplayout.layout()) figure.draw(range(len(data)),data,lable="原始值",limit_max=limit_max,limit_min=limit_min) figure.draw(dat_count,y,lable="权重") # figure.save(self._save_path,str(self._item_index)+".") self.__items.append((figure,tplayout,self._item_index)) self._item_index+=1 def calc_item_end_slot(self,data:list): print("calc_item end.") widget=QWidget() widget.setGeometry(QRect(0,0,1200,20000)) for i in data: self.add_item(i) widget.setLayout(self.__layout) self.__scroll.setWidget(widget) def calc_item(self,data,name:str): length=len(data) # 排序,从小到大 sort_list=np.sort(data) dat_count=np.bincount(data) avg=round(np.average(data)) max=sort_list[-1] min=sort_list[0] mid=sort_list[len(sort_list)//2] std=round(np.std(data)) # 把众数和原始值对齐 dat_count=dat_count[min:] dat_count_max=np.max(dat_count) dat_zoom=length//dat_count_max dat_count=np.multiply(dat_count,dat_zoom) # 去掉极大值,去掉极小值,使用99.8%的数据来统计区间 limit_max_t=sort_list[-(length//1000)] limit_min_t=sort_list[(length//1000)] limit_max=limit_max_t+(limit_max_t-limit_min_t)//5 limit_min=limit_min_t-(limit_max_t-limit_min_t)//5 # 使用3倍标准差来统计区间 # limit_max=avg+3*std # limit_min=avg-3*std if(limit_min<0): limit_min=0 x=range(length) y=np.add(range(len(dat_count)),min) dat_struct={"name":name,"max":max,"min":min,"avg":avg,"mid":mid,"std":std,"limit_max":limit_max, "limit_min":limit_min,"dat_count":dat_count,"y":y,"x":x,"data":data} # self.add_item_signal.emit(dat_struct) return dat_struct # 连接的绘制的方法 def import_but_clicked(self): self.sch_data=scheme_data.sch_data() self.__import_but.setEnabled(False) ack=self.sch_data.select_scheme() if(ack!=True): return self._save_path="file/"+self.sch_data.scheme_name.split('/')[-1].split('.')[0] print(self._save_path) self.recv_data() def recv_data(self): self._item_index=0 def recv_data_thread(sch_data:scheme_data.sch_data): titles,data,num=sch_data.datas_sql() print("recv data,len=",num) self.data_recv_end_signal.emit(titles,data) if(num<1000): print("data len too less.") return items_data=[] for i in range(len(titles)): a=self.calc_item(data[i],titles[i]) items_data.append(a) self.calc_item_end_signal.emit(items_data) t = threading.Thread(target=recv_data_thread, args=(self.sch_data,)) t.start() def data_recv_end_slot(self,titles:list,data:list): self.titles=titles self.sql_data=data print("data recv end.") def export_but_clicked(self): ret_limit=[] ret_values=[] for i,t in zip(self.__items,self.titles): max=i[1].item_value(t+":LimitMax") min=i[1].item_value(t+":LimitMin") ret_limit.append((max,min)) ret_values.append(i[1].values()) i[0].save(self._save_path,str(i[2])+".") self.sch_data.export_scheme(self._save_path,ret_limit) self.sch_data.export_check_data(self._save_path) build_html.html_build(self._save_path,self.titles,ret_values) # 运行程序 if __name__ == '__main__': app = QApplication(sys.argv) main_window = Analysis() main_window.show() app.exec()