| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  | #coding:utf-8 | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  | # 导入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 | 
					
						
							| 
									
										
										
										
											2023-10-19 18:17:09 +08:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2023-10-20 16:31:11 +08:00
										 |  |  | import build_html | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  | plt.rcParams['font.sans-serif']=['SimHei'] | 
					
						
							|  |  |  | plt.rcParams['axes.unicode_minus']=False | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  | # 定义一个可以嵌入到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) | 
					
						
							| 
									
										
										
										
											2023-10-19 18:17:09 +08:00
										 |  |  |         self._title=title | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |     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() | 
					
						
							| 
									
										
										
										
											2023-10-19 18:17:09 +08:00
										 |  |  |     def save(self,path:str,perfix:str): | 
					
						
							| 
									
										
										
										
											2023-10-20 16:31:11 +08:00
										 |  |  |         path=os.path.join(path,"pic") | 
					
						
							| 
									
										
										
										
											2023-10-19 18:17:09 +08:00
										 |  |  |         if not os.path.exists(path): | 
					
						
							|  |  |  |             os.makedirs(path) | 
					
						
							|  |  |  |         name=os.path.join(path,perfix+self._title) | 
					
						
							|  |  |  |         self.__figure.savefig(name+'.png') | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |     def lable(self,lablex,labley): | 
					
						
							|  |  |  |         self.__ax.set_ylabel(labley) | 
					
						
							|  |  |  |         self.__ax.set_xlabel(lablex) | 
					
						
							|  |  |  |     def canvas(self): | 
					
						
							|  |  |  |         return self.__canvas | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  | # 定义一个任务需要的参数布局 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  | class Analysis(QWidget): | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |     data_recv_end_signal =pyqtSignal([list,list]) | 
					
						
							|  |  |  |     calc_item_end_signal =pyqtSignal([list]) | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |     def __init__(self,parent=None): | 
					
						
							|  |  |  |         super(Analysis,self).__init__(parent) | 
					
						
							|  |  |  |         self.setWindowTitle("检测数据分析") | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |         self.calc_item_end_signal.connect(self.calc_item_end_slot) | 
					
						
							|  |  |  |         self.data_recv_end_signal.connect(self.data_recv_end_slot) | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |         self.__import_but = QPushButton("导入方案",self) | 
					
						
							|  |  |  |         self.__import_but.clicked.connect(self.import_but_clicked) | 
					
						
							|  |  |  |         self.__import_but.setGeometry(QRect(0,0,100,27)) | 
					
						
							| 
									
										
										
										
											2023-10-20 16:31:11 +08:00
										 |  |  |         self.__export_but = QPushButton("导出数据") | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |         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=[] | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |     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="权重") | 
					
						
							| 
									
										
										
										
											2023-10-20 16:31:11 +08:00
										 |  |  |         # figure.save(self._save_path,str(self._item_index)+".") | 
					
						
							|  |  |  |         self.__items.append((figure,tplayout,self._item_index)) | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |     def calc_item(self,data,name:str): | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |         # 使用3倍标准差来统计区间 | 
					
						
							|  |  |  |         # limit_max=avg+3*std | 
					
						
							|  |  |  |         # limit_min=avg-3*std | 
					
						
							|  |  |  |         if(limit_min<0): | 
					
						
							|  |  |  |             limit_min=0 | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |         x=range(length) | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |         y=np.add(range(len(dat_count)),min) | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2023-09-15 18:52:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |     # 连接的绘制的方法 | 
					
						
							|  |  |  |     def import_but_clicked(self): | 
					
						
							| 
									
										
										
										
											2023-09-18 18:16:26 +08:00
										 |  |  |         self.sch_data=scheme_data.sch_data() | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |         self.__import_but.setEnabled(False) | 
					
						
							| 
									
										
										
										
											2023-10-22 23:27:44 +08:00
										 |  |  |         ack=self.sch_data.select_scheme() | 
					
						
							|  |  |  |         if(ack!=True): | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2023-10-19 18:17:09 +08:00
										 |  |  |         self._save_path="file/"+self.sch_data.scheme_name.split('/')[-1].split('.')[0] | 
					
						
							|  |  |  |         print(self._save_path) | 
					
						
							| 
									
										
										
										
											2023-10-19 23:11:44 +08:00
										 |  |  |         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.") | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |     def export_but_clicked(self): | 
					
						
							|  |  |  |         ret_limit=[] | 
					
						
							| 
									
										
										
										
											2023-10-20 16:31:11 +08:00
										 |  |  |         ret_values=[] | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  |         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)) | 
					
						
							| 
									
										
										
										
											2023-10-20 16:31:11 +08:00
										 |  |  |             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) | 
					
						
							| 
									
										
										
										
											2023-09-17 22:09:11 +08:00
										 |  |  | # 运行程序 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     app = QApplication(sys.argv) | 
					
						
							|  |  |  |     main_window = Analysis() | 
					
						
							|  |  |  |     main_window.show() | 
					
						
							|  |  |  |     app.exec() |