summary表生成
1.思路
1.1基于raw data数据规整数据
1.2读取excel (pandas 模块为主)
1.3三层透视数据 图表制作(网上没有案例,此案例足够典型)(plt模块为主)
1.4按指定类型分类
1.5读取HTML模版,把报告按照模版类型进行填充
2.关键点
1.原始数据的分类处理
2.三层透视数据的搭建,利用类似关键字(自定义列表)重新分类索引值
3.对三层透视图的渲染分解
4.对每类BIN的处理
5.效果图
#---- code start ----#
1 # -*- coding: utf-8 -*- 2 # @Time : 2023/12/5 3 # @Author : alex 4 # @Site : 5 # @File : 6 # @Software: PyCharm 7 # This is a sample Python script. 8 # ============================================================================================================= # 9 import os 10 import sys 11 import datetime 12 import shutil 13 import openpyxl 14 import pdfkit 15 16 import numpy as np 17 import pandas as pd 18 import matplotlib 19 import matplotlib.pyplot as plt 20 21 from jinja2 import Environment, FileSystemLoader 22 from matplotlib.font_manager import FontProperties 23 from matplotlib import ticker 24 25 ''' 26 #---------------------------------------------------------------------------------------------------------------# 27 # 常量 全局变量 28 #---------------------------------------------------------------------------------------------------------------# 29 ''' 30 31 ''' 32 #---------------------------------------------------------------------------------------------------------------# 33 # read_excel 34 #---------------------------------------------------------------------------------------------------------------# 35 ''' 36 37 38 def read_excel(path_s1): 39 # current_directory = os.path.dirname(os.path.abspath(__file__)) 40 # print("获取当前绝对路径:",current_directory) 41 input_path_s1 = path_s1 42 # input_path_s1 = r'./3_summary_ft' # path定义要获取的文件名称的目录 43 file_name_list = os.listdir(input_path_s1) # os.listdir()方法获取文件夹名字,返回数组 44 print("获取文件夹列表:\n", file_name_list) 45 46 # 拼接路径 -- 仅仅获取第一个 47 input_path_s2 = input_path_s1 + '\\' + file_name_list[0] 48 49 # print("pandas 版本: ", pd.__version__) 50 # 读取一张Sheet 要读取的工作表可以由参数 sheet_name 指定。通过以 0 开头的数字或工作表名称指定。 51 work_pd1 = pd.read_excel(io=input_path_s2, sheet_name=0, header=None) # 52 pd.set_option('display.max_columns', None) # 显示完整的行 53 pd.set_option('display.max_rows', None) # 显示完整的列 54 pd.set_option('display.expand_frame_repr', False) # 设置不折叠数据 55 pd.set_option('display.float_format', lambda x: '%.2f' % x) # 设置不以科学计数法显示 56 # 读取导入Excel所有数据, 57 # print(work_pd1) 58 # print(type(work_pd1)) 59 60 return work_pd1 61 62 63 ''' 64 # ====================================================================================================================# 65 # 按月分类 66 # ====================================================================================================================# 67 ''' 68 # 构造二维数组 69 var_list_month_v12_n = [[], [], [], [], [], [], [], [], [], [], [], [], []] 70 71 72 def monthly_class_handle_v12(input_month, intput_index): 73 # print('传入参数: 月份%s 行号%s' % (input_month, intput_index)) 74 month_def = ['0', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'] 75 for index_v1 in range(1, 13): # 从1开始遍历 76 # print('遍历每月找到对应月份:',index_v1 , input_month) 77 if input_month == month_def[index_v1]: 78 # print("按月分类: %s \t行号:%s" % (month_def[index_v1], intput_index) , '月份类型:',type( month_def[index_v1])) 79 month_index = int(month_def[index_v1]) 80 # print('转换后int-月份类型: ', type(month_index), month_index) 81 # 添加数据到二维数组中 82 var_list_month_v12_n[month_index].append(intput_index) 83 # print('对应当月的行数汇总:',var_list_month_v12_n[month_index]) 84 85 break 86 # print('显示汇总后每月分类:',var_list_month_v12_n) 87 return var_list_month_v12_n 88 89 90 ''' 91 # ====================================================================================================================# 92 # 本月测试BIN数据 get_data_bin_v1 获取有效值 93 # ====================================================================================================================# 94 ''' 95 96 97 def get_data_bin_v1(x_column, month_h1_v1, get_data1): 98 # print(">>> 函数:get_data_bin_v1") 99 x_bin = x_column 100 single_month_handle = month_h1_v1 101 single_data = get_data1 102 name_clot_value = single_data.columns[x_bin] 103 print('DataFrame 首行中获取指定名称-无表头 - 索引值:< %s >' % name_clot_value, single_data.loc[0, x_bin]) 104 # 获取值缓存到列表中 105 list_clot_v3 = [] 106 for index_v12 in range(len(single_month_handle)): 107 # print("遍历-每月列表-行数值:",single_month_handle[index_v12], single_data.loc[single_month_handle[index_v12]][name_clot_value]) 108 list_clot_v3.append(single_data.loc[single_month_handle[index_v12]][name_clot_value]) 109 # print('list_clot_v3 获取有效值:\n', list_clot_v3) 110 return list_clot_v3 111 112 113 ''' 114 # ====================================================================================================================# 115 # 本月测试BIN数据 get_data_bin_v2获取有效值 116 # ====================================================================================================================# 117 ''' 118 119 120 def get_data_bin_v2(x_column, month_h1_v1, get_data1): 121 # print(">>> 函数:get_data_bin_v1") 122 x_bin = x_column 123 single_month_handle = month_h1_v1 124 single_data = get_data1 125 name_clot_value = single_data.columns[x_bin] 126 # print('DataFrame 首行中获取指定名称-无表头 - 索引值:< %s >' % name_clot_value,single_data.loc[0,x_bin]) 127 line_name_first = single_data.loc[0, x_bin] 128 # 获取值缓存到列表中 129 list_clot_v3 = [] 130 for index_v12 in range(len(single_month_handle)): 131 # print("遍历-每月列表-行数值:",single_month_handle[index_v12], single_data.loc[single_month_handle[index_v12]][name_clot_value]) 132 list_clot_v3.append(single_data.loc[single_month_handle[index_v12]][name_clot_value]) 133 # print('list_clot_v3 获取有效值:\n', list_clot_v3) 134 return line_name_first, list_clot_v3 135 136 137 ''' 138 # ====================================================================================================================# 139 # 创建路径/文件夹 -逻辑处理任意问题 140 # ====================================================================================================================# 141 ''' 142 143 144 def crate_monthly_path(z_data): 145 month_real_s = str(z_data) 146 month_name_s = "month_" + month_real_s 147 # print(os.getcwd()) # 获取当前工作目录路径 148 bin8_p = "\\4_result_ft\\month_report\\" + month_name_s 149 mk_file_path_v1 = os.getcwd() + bin8_p 150 if os.path.exists(mk_file_path_v1): 151 shutil.rmtree(mk_file_path_v1) 152 os.mkdir(mk_file_path_v1) 153 print("# 创建报告生成工作目录", mk_file_path_v1) 154 155 return mk_file_path_v1 156 157 158 ''' 159 # ====================================================================================================================# 160 # 本月数据 -生成报告汇总 161 # ====================================================================================================================# 162 ''' 163 164 165 def generate_report_summary(z_y1): 166 print("#**** generate_report_summary ****#") 167 # 创建路径 / 文件夹 - 逻辑处理任意问题 168 month_real = str(z_y1) 169 mk1_file_name = crate_monthly_path(month_real) 170 # print("创建新目录:",mk1_file_name) 171 172 # 拷贝文件到对应月份文件中 173 source_folder1 = r'./4_result_ft/picture' 174 target_folder2 = mk1_file_name + '/picture' 175 shutil.copytree(source_folder1, target_folder2) 176 177 # 伟测-vi5300-ft-wc 178 # 月份+路径 179 single_month_report_ft_wc(month_real, target_folder2) 180 181 182 ''' 183 # ====================================================================================================================# 184 # 本月数据 -获取本月的汇总数据 185 # ====================================================================================================================# 186 ''' 187 188 189 def get_month_total_info(y_p1, y_p2, y_p4, z_p2, z_p3, z_p4): 190 print('>>> get_month_total_info ...') 191 # 1按照总数汇总 192 y_total_k1 = y_p1 193 y_total_k2 = y_p2 194 y_yield_k4 = y_p4 195 month_u1 = z_p2 196 single_month_g1 = z_p3 197 raw_data_t1 = z_p4 198 print('汇总处理: 月份< %d >' % month_u1, ) 199 print(single_month_g1) 200 y_name_f1, y_data_j1 = get_data_bin_v2(y_total_k1, single_month_g1, raw_data_t1) 201 y_name_f2, y_data_j2 = get_data_bin_v2(y_total_k2, single_month_g1, raw_data_t1) 202 y_name_f4, y_data_j4 = get_data_bin_v2(y_yield_k4, single_month_g1, raw_data_t1) 203 print('源4:', y_name_f1, y_data_j1) # Input 204 print('源5:', y_name_f2, y_data_j2) # BIN01(Good) 205 206 # ---------------------------------------------------------------------------------------------------------------- # 207 # 1按照总数汇总 208 r1_input = np.sum(y_data_j1) 209 r1_bin1 = np.sum(y_data_j2) 210 r1_yield = r1_bin1 / r1_input 211 r1_yield_percent = "{:.2%}".format(r1_yield) 212 r1_limit = "{:.2%}".format(y_data_j4[0]) 213 r1_state = 'pass' if r1_yield > y_data_j4[0] else 'fail' 214 print('结果:%s 实际良率:%s 目标良率:%s 投入数量(ea): %d 实际产出(ea):%d \n' % (r1_state, r1_yield_percent, r1_limit, r1_input, r1_bin1,)) 215 216 217 ''' 218 # ====================================================================================================================# 219 # html_vi5300_ft_wc 伟测模版 220 # ====================================================================================================================# 221 ''' 222 223 224 def html_vi5300_ft_wc(body, s_t1, e_t2, month_jk1): 225 env = Environment(loader=FileSystemLoader(r'./4_result_ft/month_report/')) 226 test_report = env.get_template('vi5300_ft_wc_report_template.html') 227 monthly_V12_data = "./4_result_ft/month_report/month_" + month_jk1 + "/report_" + month_jk1 + "monthly_result.html" 228 # open("result.html", 'w+') as fout: 229 with open(monthly_V12_data, 'w+') as fout: 230 html_content = test_report.render(start_time=s_t1, stop_time=e_t2, body=body) 231 fout.write(html_content) 232 233 234 ''' 235 # ====================================================================================================================# 236 # single_month_report_ft_wc 获取html模板-ft伟测 237 # ====================================================================================================================# 238 ''' 239 240 241 def single_month_report_ft_wc(z_y1, z_y2): 242 print("************ single_month_report_ft_wc **********") 243 # 获取有效值 244 source_folder2 = z_y2 + "/月度_汇总统计结果.xlsx" 245 # print("h获取有效的excel",source_folder2) 246 work_book2 = openpyxl.load_workbook(source_folder2) 247 worksheet_b2 = work_book2.active 248 target_rows_x2 = worksheet_b2.max_row 249 target_cols_y2 = worksheet_b2.max_column 250 print("行列:", target_rows_x2, target_cols_y2) 251 s_status = worksheet_b2.cell(2, 2).value 252 s_yield = worksheet_b2.cell(2, 3).value 253 s_limit = worksheet_b2.cell(2, 4).value 254 s_input = worksheet_b2.cell(2, 5).value 255 s_output = worksheet_b2.cell(2, 6).value 256 # print(s_status, s_yield, s_limit, s_input, s_output) 257 258 # 259 s_month = z_y1 260 total_status = s_status 261 total_yield_p = s_yield 262 total_limit_p = s_limit 263 total_input = s_input 264 total_output = s_output 265 # ----------------------------------------------------------------------------------------------- # 266 267 # vi5300_ft_wc_report_template 268 # get_data_txt_v1 = open(r'C:\Users\chucheng.cao\Desktop\work\python\test_data\test_month_report_xx\note\bin1.txt', encoding='utf-8') 269 # txt_v1 = [] 270 # for line in get_data_txt_v1: 271 # txt_v1.append(line.strip()) 272 # print('添加测试:',txt_v1[0]) 273 274 body = [] 275 # txt_bin1 = "BIN1" + txt_v1[0] 276 txt_bin1 = "BIN1" 277 txt_handler = "handler" 278 txt_lot = "lot" 279 txt_bin3 = "BIN3" 280 txt_bin4 = "BIN4" 281 txt_bin5 = "BIN5" 282 txt_bin6_1 = "BIN6_1" 283 txt_bin6_2 = "BIN6_2" 284 txt_bin7_1 = "BIN7_1" 285 txt_bin7_2 = "BIN7_2" 286 txt_bin7_3 = "BIN7_3" 287 txt_bin9 = "BIN9" 288 txt_bin13 = "BIN13" 289 txt_bin14 = "BIN14" 290 txt_bin_vm = "BIN_vm" 291 txt_bin_loss = "BIN_loss" 292 # 图片路径 293 # 当前绝对路径-建议使用相对路径 294 source_bin1 = os.getcwd() 295 Picture_bin1 = "\\4_result_ft\\month_report" 296 picture_bin2 = "\\month_" + s_month + "\\picture\\" 297 Picture_bin_route = source_bin1 + Picture_bin1 + picture_bin2 298 print("图片路径目录:", Picture_bin_route) 299 300 result = {'serial': "1", 301 'SYL': total_limit_p, 302 'Total': total_input, 303 'BIN': total_output, 304 'Yield': total_yield_p, 305 'states': total_status, 306 'Picture_bin1': Picture_bin_route + "BIN1.jpg", 'describe_bin1': txt_bin1, 307 'Picture_handler': Picture_bin_route + "handler.jpg", 'describe_handler': txt_handler, 308 'Picture_lot': Picture_bin_route + "lot.jpg", 'describe_lot': txt_lot, 309 'Picture_bin3': Picture_bin_route + "BIN3.jpg", 'describe_bin3': txt_bin3, 310 'Picture_bin4': Picture_bin_route + "BIN4.jpg", 'describe_bin4': txt_bin4, 311 'Picture_bin5': Picture_bin_route + "BIN5.jpg", 'describe_bin5': txt_bin5, 312 'Picture_bin6_1': Picture_bin_route + "BIN6_1.jpg", 'describe_bin6': txt_bin6_1, 313 'Picture_bin6_2': Picture_bin_route + "BIN6_2.jpg", 'describe_bin6_2': txt_bin6_2, 314 'Picture_bin7_1': Picture_bin_route + "BIN7_1.jpg", 'describe_bin7_1': txt_bin7_1, 315 'Picture_bin7_2': Picture_bin_route + "BIN7_2.jpg", 'describe_bin7_2': txt_bin7_2, 316 'Picture_bin7_3': Picture_bin_route + "BIN7_3.jpg", 'describe_bin7_3': txt_bin7_3, 317 'Picture_bin9': Picture_bin_route + "BIN9.jpg", 'describe_bin9': txt_bin9, 318 'Picture_bin13': Picture_bin_route + "BIN13.jpg", 'describe_bin13': txt_bin13, 319 'Picture_bin14': Picture_bin_route + "BIN14.jpg", 'describe_bin14': txt_bin14, 320 'Picture_bin_vm': Picture_bin_route + "BIN_vm.jpg", 'describe_bin_vm': txt_bin_vm, 321 'Picture_bin_loss': Picture_bin_route + "BIN_loss.jpg", 'describe_bin_loss': txt_bin_loss, 322 323 } 324 body.append(result) 325 start_monthly = "2023." + str(s_month) + ".1" 326 stop_monthly = "2023." + str(s_month) + ".30" 327 html_vi5300_ft_wc(body, start_monthly, stop_monthly, s_month) 328 329 330 ''' 331 # ====================================================================================================================# 332 # 本月数据汇总 333 # ====================================================================================================================# 334 ''' 335 336 337 def single_month_summary_v1(single_month_m12, get_raw_data): 338 print('进入函数>>>: single_month_summary_v1 ...') # 注意索引值从0开始,索引1==第1月 339 ''' 340 # # 默认值,后续直接修改月份 341 # month_handle_v1 = 11 342 # # print('举例11月份数据', single_month_m12[month_handle_v1]) 343 # all_data = get_raw_data 344 345 # # ---------------------------------------------------------------------------------------------------------------- # 346 # print('打印全部数据\n',pd.DataFrame(all_data)) 347 # print('打印单行数据\n',pd.DataFrame(all_data.iloc[14])) 348 # print('打印行列标签\n',pd.DataFrame(all_data.axes)) 349 # print('判断输入数据是否为空\n', all_data.empty) 350 # print('DataFrame 维度的元组(行,列)\n', all_data.shape) 351 # print('DataFrame具体位置 \n', all_data.loc[12][0]) 352 # print('DataFrame 首行名称 \n',all_data.columns) 353 # # ---------------------------------------------------------------------------------------------------------------- # 354 # # 无表头 - 获取CLOT 355 # # print('DataFrame 首行名称 \n', all_data.columns) 356 # 357 # name_clot = 4 # lot id 358 # print('DataFrame 首行中获取指定名称-无表头:', all_data.columns[name_clot]) 359 # name_clot_value = all_data.columns[name_clot] 360 # print('索引值:< %s >' % name_clot_value) 361 # 362 # # 获取值缓存到列表中 363 # list_clot_v2 = [] 364 # for index_v12 in range(len(single_month_m12[month_handle_v1])): 365 # # print("遍历-每月列表-行数值:",single_month_m12[month_handle_v1][index_v12]) 366 # # print( all_data.loc[var_list_month_v12_n[month_handle_v1][index_v12]][name_clot_value]) 367 # # var_list_clot_v2.append(all_data.loc[var_list_month_v12_n[month_handle_v1][index_v12]][name_clot_value]) 368 # list_clot_v2.append(all_data.loc[single_month_m12[month_handle_v1][index_v12]][name_clot_value]) 369 # print('var_list_clot_v2 获取有效值:\n', list_clot_v2) 370 # # ---------------------------------------------------------------------------------------------------------------- # 371 # print('获取全部数据1: \n',all_data.loc[: , :].values) 372 # print('获取全部数据2: \n', all_data.iloc[:, :].values) 373 # 无表头- 获取某个值 第i行第j列的值,返回类型依内容而定 374 # print("无表头- 获取某个值1: ", all_data.loc[1, 0]) 375 # print("无表头- 获取某个值2: ", all_data.iloc[1, 0]) 376 # 获取某一行 第i行数据,返回类型为ndarray(一维) 377 # print("无表头- 获取某个行1: \n", all_data.loc[12].values) 378 # print("无表头- 获取某个行2: \n", all_data.iloc[12].values) 379 # 获取多行:第i1、i2、i3行数据,返回类型为ndarray(二维) 380 # print("无表头- 获取多行1: \n", all_data.loc[[12,13]].values) 381 # print("无表头- 获取多行2: \n", all_data.iloc[[12, 13]].values) 382 # 无表头 -- 获取某一列: 第j列数据,返回类型为ndarray(一维) 383 # print("无表头- 获取某个列1: \n", all_data.loc[:,0].values) 384 # print("无表头- 获取某个列2: \n", all_data.iloc[:, 0].values) 385 # 无表头 -- 获取多列:第j1、j2列数据,返回类型为ndarray(二维) 386 # print("无表头- 获取多列1: \n", all_data.loc[:, [0 , 1]].values) 387 # print("无表头- 获取多列2: \n", all_data.iloc[:, [0, 1]].values) 388 # 无表头 --获取切片:行号[i1,i2]、列号[j1,j2]闭区间内的数据,行号[i1,i2)、列号[j1,j2)左闭右开区间内的数据,类型为ndarray(二维) 389 # print('无表头 --获取切片1:\n', all_data.loc[10:15, 0:3].values) 390 # print('无表头 --获取切片2:\n', all_data.iloc[10:15, 0:3].values) 391 # # 举例:有表头 获取多列:第j1、j2列数据,,‘姓名’、‘性别’列数据, 第j1、j2列数据,返回类型为ndarray(二维)。 392 # # all_data.loc[:, [“姓名”,“性别”]].values 393 # # all_data.iloc[:, [0 , 3]].values 394 # 介绍 395 # loc和iloc方法是通过索引定位的方式获取数据的,写法为loc[A, B]和iloc[A, B]。 396 # 其中A表示对行的索引,B表示对列的索引,B可缺省。A、B可为列表或i1:i2(切片)的形式,表示多行或多列。 397 # 这两个方法的区别是,loc将参数当作标签处理,iloc将参数当作索引号处理。 398 # 也就是说,在有表头的方式中,当列索引使用str标签时,只可用loc,当列索引使用索引号时,只可用iloc; 399 # 在无表头的方式中,索引向量也是标签向量,loc和iloc均可使用;在切片中,loc是闭区间,iloc是半开区间。 400 # # ---------------------------------------------------------------------------------------------------------------- # 401 # 规整lot_id 参考函数 402 # lot_list_v1 = [] 403 # wafer_list_v1 = [] 404 # for index_a in range(len(c_g_data1)): 405 # # print(index_a,c_g_data1[index_a],type(c_g_data1[index_a])) 406 # str_v1_lot = c_g_data1[index_a][0:6] 407 # str_v1_wafer =c_g_data1[index_a][7:9] 408 # lot_list_v1.append(str_v1_lot) 409 # wafer_list_v1.append(str_v1_wafer) 410 # print('切片lot : ',lot_list_v1) 411 # print('wafer: ',wafer_list_v1) 412 # one_lot = [] 413 # for v2_lot in lot_list_v1 : 414 # if v2_lot not in one_lot: 415 # one_lot.append(v2_lot) 416 # print('唯一lot: ', one_lot) 417 # 418 # peopleidlistunique = list(set(lot_list_v1)) # 去重 419 # new_lot = [] 420 # for i_v1 in peopleidlistunique: 421 # # print("元素", i_v1, "出现了", lot_list_v1.count(i_v1), "次") # 统计数量并输出 422 # for i in range(lot_list_v1.count(i_v1)): 423 # new_lot.append(i_v1) 424 # print('唯一补齐lot: ', new_lot) 425 ''' 426 427 # # TODO 默认值11,后续直接修改月份 428 month_h1 = 11 429 s_m_m12 = single_month_m12[month_h1] # 获取本月行号索引值 430 raw_data_h1 = get_raw_data # 获取整excel表句柄 431 # ---------------------------------------------------------------------------------------------------------------- # 432 time_s = datetime.datetime.now() 433 print("\ntime_1 :", time_s) 434 # TODO 手动输入实际模版 435 # 使用无表头,使用数字强制索引 436 ''' 437 u1_handler = 1 438 u1_lot = 4 439 u1_marking = 8 440 u1_yield = 11 441 u1_input = 12 442 u1_bin1 = 13 443 u1_bin1_p = 14 444 u1_bin3 = 17 445 u1_bin3_p = 18 446 u1_bin4 = 19 447 u1_bin4_p = 20 448 u1_bin5 = 21 449 u1_bin5_p = 22 450 u1_bin6 = 23 451 u1_bin6_p = 24 452 u1_bin7 = 25 453 u1_bin7_p = 26 454 u1_bin9 = 29 455 u1_bin9_p = 30 456 u1_bin13 = 31 457 u1_bin13_p = 32 458 u1_bin14 = 33 459 u1_bin14_p = 34 460 u1_bin_vm = 35 461 u1_bin_vm_p = 36 462 u1_bin_loss = 37 463 u1_bin_loss_p = 38 464 u1_bin3_os = 39 465 u1_bin3_os_p = 40 466 u1_bin4_iih = 41 467 u1_bin4_iih_p = 42 468 u1_bin5_cal = 43 # calibration 469 u1_bin5_cal_p = 44 470 u1_bin6_vf = 45 # verify 471 u1_bin6_vf_p = 46 472 u1_bin6_ck = 47 # Crosstalk 473 u1_bin6_ck_p = 48 474 u1_bin7_power = 49 475 u1_bin7_power_p = 50 476 u1_bin7_os = 51 477 u1_bin7_os_p = 52 478 u1_bin7_lk = 53 479 u1_bin7_lk_p = 54 # Leakage 480 ''' 481 u1_handler = 1 482 u1_lot = 4 483 u1_marking = 9 # xx=9 we=8 ? 484 u1_yield = 13 # xx=13 xx=12 485 u1_input = 14 486 u1_bin1 = 15 487 u1_bin1_p = 16 488 u1_bin3 = 19 489 u1_bin3_p = 20 490 u1_bin4 = 21 491 u1_bin4_p = 22 492 u1_bin5 = 23 493 u1_bin5_p = 24 494 u1_bin6 = 25 495 u1_bin6_p = 26 496 u1_bin7 = 27 497 u1_bin7_p = 28 498 u1_bin9 = 31 499 u1_bin9_p = 32 500 u1_bin13 = 33 501 u1_bin13_p = 34 502 u1_bin14 = 35 503 u1_bin14_p = 36 504 u1_bin_vm = 37 505 u1_bin_vm_p = 38 506 u1_bin_loss = 39 507 u1_bin_loss_p = 40 508 u1_bin3_os = 41 509 u1_bin3_os_p = 42 510 u1_bin4_iih = 43 511 u1_bin4_iih_p = 44 512 u1_bin5_cal = 45 # calibration 513 u1_bin5_cal_p = 46 514 u1_bin6_vf = 47 # verify 515 u1_bin6_vf_p = 48 516 u1_bin6_ck = 49 # Crosstalk 517 u1_bin6_ck_p = 50 518 u1_bin7_power = 51 519 u1_bin7_power_p = 52 520 u1_bin7_os = 53 521 u1_bin7_os_p = 54 522 u1_bin7_lk = 55 523 u1_bin7_lk_p = 56 # Leakage 524 525 # display_all_header_file_names(53, global_single_month_data, global_all_month_raw_data) 526 # display_all_header_file_names(54, global_single_month_data, global_all_month_raw_data) 527 # ---------------------------------------------------------------------------------------------------------------- # 528 time_s = datetime.datetime.now() 529 print("\ntime_s :", time_s, ) 530 # ---------------------------------------------------------------------------------------------------------------- # 531 # 具体BIN1处理 通用处理 532 # ---------------------------------------------------------------------------------------------------------------- # 533 name_bin = "BIN1" 534 reorder_bin_info(u1_marking, u1_handler, u1_lot, u1_input, u1_bin1, u1_bin1_p, u1_yield, name_bin, month_h1, s_m_m12, raw_data_h1) 535 chart_total_info(u1_marking, u1_handler, u1_lot, u1_input, u1_bin1, u1_bin1_p, u1_yield, name_bin, month_h1, s_m_m12, raw_data_h1) 536 537 # ---------------------------------------------------------------------------------------------------------------- # 538 # 具体不良品处理 特殊处理 539 # name_bin = "BIN2" 不存在 540 541 # 542 name_bin = "BIN3" 543 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin3, u1_bin3_os, u1_bin3_p, u1_bin3_os_p, name_bin, month_h1, s_m_m12, raw_data_h1) 544 # 545 name_bin = "BIN4" 546 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin4, u1_bin4_iih, u1_bin4_p, u1_bin4_iih_p, name_bin, month_h1, s_m_m12, raw_data_h1) 547 # 548 name_bin = "BIN5" 549 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin5, u1_bin5_cal, u1_bin5_p, u1_bin5_cal_p, name_bin, month_h1, s_m_m12, raw_data_h1) 550 # 551 name_bin = "BIN6_1" 552 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin6, u1_bin6_vf, u1_bin6_p, u1_bin6_vf_p, name_bin, month_h1, s_m_m12, raw_data_h1) 553 name_bin = "BIN6_2" 554 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin6, u1_bin6_ck, u1_bin6_p, u1_bin6_ck_p, name_bin, month_h1, s_m_m12, raw_data_h1) 555 # 556 name_bin = "BIN7_1" 557 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin7, u1_bin7_power, u1_bin7_p, u1_bin7_power_p, name_bin, month_h1, s_m_m12, raw_data_h1) 558 name_bin = "BIN7_2" 559 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin7, u1_bin7_os, u1_bin7_p, u1_bin7_os_p, name_bin, month_h1, s_m_m12, raw_data_h1) 560 name_bin = "BIN7_3" 561 defective_handle_v2(u1_marking, u1_handler, u1_lot, u1_bin7, u1_bin7_lk, u1_bin7_p, u1_bin7_lk_p, name_bin, month_h1, s_m_m12, raw_data_h1) 562 # 563 name_bin = "BIN9" 564 defective_handle_v2_se(u1_marking, u1_handler, u1_lot, u1_bin9, u1_bin9_p, name_bin, month_h1, s_m_m12, raw_data_h1) 565 name_bin = "BIN13" 566 defective_handle_v2_se(u1_marking, u1_handler, u1_lot, u1_bin13, u1_bin13_p, name_bin, month_h1, s_m_m12, raw_data_h1) 567 name_bin = "BIN14" 568 defective_handle_v2_se(u1_marking, u1_handler, u1_lot, u1_bin14, u1_bin14_p, name_bin, month_h1, s_m_m12, raw_data_h1) 569 name_bin = "BIN_vm" 570 defective_handle_v2_se(u1_marking, u1_handler, u1_lot, u1_bin_vm, u1_bin_vm_p, name_bin, month_h1, s_m_m12, raw_data_h1) 571 name_bin = "BIN_loss" 572 defective_handle_v2_se(u1_marking, u1_handler, u1_lot, u1_bin_loss, u1_bin_loss_p, name_bin, month_h1, s_m_m12, raw_data_h1) 573 574 # ---------------------------------------------------------------------------------------------------------------- # 575 time_e = datetime.datetime.now() 576 print("\ntime_s :", time_e, "耗时:", (time_e - time_s)) 577 578 579 ''' 580 # ====================================================================================================================# 581 # 本月-良品BIN1-测试数据汇总分布-通用模板1数据处理 582 # ====================================================================================================================# 583 ''' 584 585 586 def reorder_bin_info(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 587 # ---------------------------------------------------------------------------------------------------------------- # 588 # 开始计时 589 datetime_object_11 = datetime.datetime.now() 590 print("datetime_object_11 :", datetime_object_11) 591 592 # 使用无表头,使用数字强制索引 -- 第一份引用 593 x_handler_n2 = x_p2 594 x_lot_n3 = x_p3 595 month_n2 = z_p2 596 single_month_d2 = z_p3 597 raw_data_a2 = z_p4 598 599 # 使用无表头,使用数字强制索引 -- 第一份引用 600 u2_marking = x_p1 601 u2_handler = x_p2 602 u2_lot = x_p3 603 u2_input = y_p1 604 u2_bin1 = y_p2 605 u2_bin1_p = y_p3 606 u2_yield = y_p4 607 u2_name = z_p1 608 u2_month = z_p2 609 u2_index_m12 = z_p3 610 u2_raw_data = z_p4 611 612 # ---------------------------------------------------------------------------------------------------------------------- # 613 # 处理1 数据归类 614 print('绘图处理: 月份< %d >' % month_n2, z_p1) 615 616 # 指定月份 - 归类前文件 617 c_g_name1, c_g_data1 = get_data_bin_v2(x_lot_n3, single_month_d2, raw_data_a2) 618 c_g_name2, c_g_data2 = get_data_bin_v2(x_handler_n2, single_month_d2, raw_data_a2) 619 print("源1:", c_g_name1, c_g_data1) 620 print("源2:", c_g_name2, c_g_data2) 621 622 # ---------------------------------------------------------------------------------------------------------------- # 623 lot_list_v1 = [] 624 lot_list_v3 = [] 625 for index_a in range(len(c_g_data1)): 626 num_v1_lot = single_month_d2[index_a] # 获取本月行号 索引值 627 str_v1_lot = c_g_data1[index_a][0:6] # 正则表达获取lot ,去除wafer 628 lot_handler_t1 = c_g_data2[index_a] # 获取附属信息 handler 629 lot_list_v2 = [num_v1_lot, str_v1_lot, lot_handler_t1] # 3个关键字存储到一维列表中 630 lot_list_v1.append(lot_list_v2) # 存储到一维列表到二维列表中 631 lot_list_v3.append(str_v1_lot) # 1个关键字存储到一维列表中 632 # all raw data 有效映射 633 # print('all data -- 切片lot : ', len(lot_list_v1), lot_list_v1) 634 635 # 获取同一列表中相同元素,只保留一种类型 636 one_lot = [] 637 for v2_lot in lot_list_v3: 638 if v2_lot not in one_lot: 639 one_lot.append(v2_lot) 640 print('lot中唯一代表名称: ', one_lot) 641 642 # 先按照 lot 分类 再按照 handler分类 最后索引-行号 643 lot_handler_m1 = [] # 重新分类聚合的列表 644 lot_h1_m1 = [] 645 lot_h1_m2 = [] 646 # 先按照 lot 大类分组 647 for row_v1_w1 in one_lot: 648 # print('每种类型的lot: ',row_v1_w1) 649 line_re_lot5 = [] 650 651 for row_v1 in lot_list_v1: 652 # print('切片lot中第1个元素-二维列中每行第1个元素: ',row_v1[1]) 653 if row_v1_w1 == row_v1[1]: 654 # print('打印相同的元素名称: ',row_v1_w1,row_v1[0],row_v1[1]) 655 line_re_lot4 = [row_v1[0], row_v1[1], row_v1[2]] # 按照每个lot大类重新组合索引值 656 line_re_lot5.append(line_re_lot4) 657 lot_h1_m1.append(row_v1[0]) 658 lot_h1_m2.append(line_re_lot4) 659 # print('每个lot大类-组合: ',line_re_lot5) 660 661 # 每个lot类 再按照 handler 重新分类 662 re_handler_1 = [] 663 re_handler_2 = [] 664 re_handler_3 = [] 665 re_handler_4 = [] 666 re_handler_x = [] 667 handler_name_d = ["handler0 名称:", "HIP-01", "HIP-02", "HIP-03", "HIP-04", ] # TODO g根据机台重新添加 668 for two_m1 in line_re_lot5: 669 # print('每个lot中 handler元素组合:',two_m1,two_m1[2]) 670 if handler_name_d[1] == two_m1[2]: 671 # print('具体handler匹配: ',handler_name_d[1],two_m1[2]) 672 re_handler_1.append(two_m1[0]) # handler1 673 elif handler_name_d[2] == two_m1[2]: 674 re_handler_2.append(two_m1[0]) # handler2 675 elif handler_name_d[3] == two_m1[2]: 676 re_handler_3.append(two_m1[0]) # handler3 677 elif handler_name_d[4] == two_m1[2]: 678 re_handler_4.append(two_m1[0]) # handler4 679 else: 680 re_handler_x.append(two_m1[0]) # handler x 未知分类 681 682 # 一维列表合并 683 re_handler_m = re_handler_1 + re_handler_2 + re_handler_3 + re_handler_4 + re_handler_x 684 # print("按照handler 子归类:", re_handler_m) 685 lot_handler_m1.append(re_handler_m) # 一维列表组合成二维列表 686 # ---------------------------------------------------------------------------------------------------------------- # 687 # 显示分组情况 688 # 第1种情况 689 # print('仅按照大类lot分组:',len(lot_h1_m2),lot_h1_m2) 690 # print('仅按照大类lot分组-索引行号:', len(lot_h1_m1), lot_h1_m1) 691 692 # 第2种情况 693 # print("lot_handler_ 分组二维列表:", len(lot_handler_m1), lot_handler_m1) 694 # 二维列表转一维列表 非常重要 695 lot_handler_m1_result = [n for a in lot_handler_m1 for n in a] 696 print('最终结果 -- lot_handler_m1_result: ', lot_handler_m1_result) 697 698 # # 第3种情况 - 仅仅按照handler分类 顺序重新归类 699 # reclassify_1 = [] 700 # reclassify_2 = [] 701 # reclassify_3 = [] 702 # reclassify_4 = [] 703 # reclassify_x = [] 704 # handler_name = ["handler0 名称:", "HIP-01", "HIP-02", "HIP-03", "HIP-04", ] 705 # for two_m1 in range(len(single_month_m12[month_h1])): 706 # # print('按照handler 分组',single_month_m12[month_h1][two_m1]) 707 # if handler_name[1] == c_g_data2[two_m1]: 708 # reclassify_1.append(single_month_m12[month_h1][two_m1]) # handler1 709 # elif handler_name[2] == c_g_data2[two_m1]: 710 # reclassify_2.append(single_month_m12[month_h1][two_m1]) # handler2 711 # elif handler_name[3] == c_g_data2[two_m1]: 712 # reclassify_3.append(single_month_m12[month_h1][two_m1]) # handler3 713 # elif handler_name[4] == c_g_data2[two_m1]: 714 # reclassify_4.append(single_month_m12[month_h1][two_m1]) # handler4 715 # else: 716 # reclassify_x.append(single_month_m12[month_h1][two_m1]) # handler x 717 # handler_merged_result3 = reclassify_1 + reclassify_2 + reclassify_3 + reclassify_4 + reclassify_x 718 # print("按照handler 重新归类 索引值: ",handler_merged_result3) 719 720 # 用目标值 替换源列表中 行分组 721 single_month_d2 = lot_handler_m1_result 722 # single_month_m12[month_h1] = handler_merged_result3 723 # 显示新月份所有的月度索引值-行号 724 # for index_a in range(1, 13): 725 # print('第%d月数据' % (index_a), single_month_m12[index_a]) 726 # 新索引值重新被引用 727 index_s_m2 = single_month_d2 728 729 datetime_object_12 = datetime.datetime.now() 730 print("datetime_object_12 :", datetime_object_12, ' 耗时:', (datetime_object_12 - datetime_object_11)) 731 732 # ---------------------------------------------------------------------------------------------------------------------- # 733 # 绘图 是由上述函数传递的:index_s_m2 734 histogram_handle_v1(u2_marking, u2_handler, u2_lot, u2_input, u2_bin1, u2_bin1_p, u2_yield, u2_name, u2_month, index_s_m2, u2_raw_data) 735 736 datetime_object_13 = datetime.datetime.now() 737 print("datetime_object_12 :", datetime_object_13, ' 耗时:', (datetime_object_13 - datetime_object_11)) 738 739 740 ''' 741 # ====================================================================================================================# 742 # 本月-良品BIN1-测试数据汇总分布-绘图1 743 # ====================================================================================================================# 744 ''' 745 746 747 def histogram_handle_v1(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 748 print('#---- histogram_handle_v1 ----#') 749 x_axle_n1 = x_p1 750 x_axle_n2 = x_p2 751 x_axle_n3 = x_p3 752 y_total_t1 = y_p1 753 y_total_t2 = y_p2 754 y_yield_t1 = y_p3 755 y_yield_t2 = y_p4 756 bin_name = z_p1 757 month_n1 = z_p2 758 single_month_d1 = z_p3 759 raw_data_a1 = z_p4 760 print('绘图处理: 月份< %d >' % month_n1, ) 761 # 获取每月函数 有效数据 x_axle_n2 762 x_name1, x_data1 = get_data_bin_v2(x_axle_n1, single_month_d1, raw_data_a1) 763 x_name2, x_data2 = get_data_bin_v2(x_axle_n2, single_month_d1, raw_data_a1) 764 x_name3, x_data3 = get_data_bin_v2(x_axle_n3, single_month_d1, raw_data_a1) 765 y_name1, y_data1 = get_data_bin_v2(y_total_t1, single_month_d1, raw_data_a1) 766 y_name2, y_data2 = get_data_bin_v2(y_total_t2, single_month_d1, raw_data_a1) 767 y_name3, y_data3 = get_data_bin_v2(y_yield_t1, single_month_d1, raw_data_a1) 768 y_name4, y_data4 = get_data_bin_v2(y_yield_t2, single_month_d1, raw_data_a1) 769 # print(x_name1, x_data1) 770 # print(x_name2, x_data2) 771 # print(y_name1, y_data1) 772 # print(y_name2, y_data2) 773 # print(y_name3, y_data3) 774 775 # ======================================================================================== # 776 777 # 整体参数配置 778 font = FontProperties(size=10) 779 plt.rcParams["font.sans-serif"] = ['SimHei'] 780 plt.rcParams['axes.unicode_minus'] = False 781 plt.rcParams['font.family'] = ['SimHei'] 782 plt.rcParams['font.sans-serif'] = ['SimHei'] 783 plt.rcParams['figure.figsize'] = (30, 10) 784 plt.rc('font', family='SimHei', size=8) 785 786 # 创建一个图形和两个y轴 787 fig, ax1 = plt.subplots(1, 1) # 绘制双Y轴 表示一次性在figure上创建成1*1的网格 788 789 # 柱状图柱子宽度 790 bar_width = 0.4 791 x_ticks = range(len(x_data1)) # x轴刻度位置 | 折线图x位置 792 bar_1_x = [(ii - bar_width + 0.2) for ii in x_ticks] # 柱状图1 - x位置 793 bar_2_x = [(ww - bar_width + 0.6) for ww in x_ticks] 794 795 # 设置x轴刻度字体以及方向-单刻度标签 796 labels1 = ax1.get_xticklabels() + ax1.get_yticklabels() 797 [label.set_fontname('SimHei') for label in labels1] 798 # plt.xticks(x_ticks, list(x_data1), rotation=90, ) #x轴刻度位置 | 刻度标签 | 旋转90度 799 800 # 设置x轴刻度字体以及方向- 叠加双刻度标签 801 labels = [] 802 for two_m1 in range(len(x_data1)): 803 cell_m2 = x_data3[two_m1][0:6] + ' ' + x_data2[two_m1] + ' ' + x_data1[two_m1] 804 labels.append(cell_m2) 805 # labels = x_ticks # 默认 806 # print('2个叠加后的刻度标签: ',labels) # 2个叠加后的刻度标签 807 plt.xticks(x_ticks, labels, rotation=90, ) # x轴刻度位置 | 刻度标签 | 旋转90度 808 # 自适应调整布局+ 指定 解决X轴范围问题 809 fig.autofmt_xdate(rotation=90) 810 811 # -------------------------------------------------------------------------------------- # 812 # # 同一刻度标签标记为不同颜色 插孔法 813 # 第1种方案 814 # xtick_labels = ax1.get_xticklabels() 815 # colors = ['red', 'green', 'blue', 'purple', 'orange', 'black', 'brown', 'gray', 'pink', 'yellow', 'cyan', 'magenta'] 816 # for x_colors in range(int(len(x_data1)/4)): 817 # # print(0+x_colors*4, 1+x_colors*4, 2+x_colors*4,3+x_colors*4) 818 # x_colors_a = 0 + x_colors * 4 819 # x_colors_b = 1 + x_colors * 4 820 # x_colors_c = 2 + x_colors * 4 821 # x_colors_d = 3 + x_colors * 4 822 # pass 823 # xtick_labels[x_colors_a].set_color('red') 824 # xtick_labels[x_colors_b].set_color('blue') 825 # xtick_labels[x_colors_c].set_color('orange') 826 # xtick_labels[x_colors_d].set_color('magenta') 827 # 828 # 升级-适用较为复杂的场景 829 # 第2种方案 830 print(x_name1) 831 print(x_name2) 832 print(x_name3) 833 834 index_lot_v5 = [] 835 for index_a in range(len(single_month_d1)): 836 index_lot = single_month_d1[index_a] # 获取本月行号 索引值 837 index_m1 = x_data3[index_a][0:6] # 获取本月行号 索引值 838 index_lot_v5.append(index_m1) 839 # all raw data 有效映射 840 print("all raw data 有效映射:", index_lot_v5) 841 # 获取同一列表中相同元素,只保留一种类型 842 one_lot_v1 = [] 843 for v2_lot in index_lot_v5: 844 if v2_lot not in one_lot_v1: 845 one_lot_v1.append(v2_lot) 846 print('lot中唯一代表名称: ', one_lot_v1) 847 xtick_labels = ax1.get_xticklabels() 848 colors = ['red', 'green', 'blue', 'purple', 'orange', 'brown', 'gray', 'pink', 'cyan', 'magenta', 'yellow', 'black', ] 849 # 利用唯一lot去适配列表lot,影射到对应刻度,根据余数去自动识别颜色,默认10种 850 for x_color in range(len(x_data3)): 851 # print("x_color: ",x_color,x_data3[x_color][0:6]) 852 for one_c1 in range(len(one_lot_v1)): 853 # print("Index:", one_c1, "Value:", one_lot_v1[one_c1]) 854 if one_lot_v1[one_c1] == x_data3[x_color][0:6]: 855 one_color_v1 = one_c1 % 10 856 if one_color_v1 == 0: 857 xtick_labels[x_color].set_color(colors[0]) 858 elif one_color_v1 == 1: 859 xtick_labels[x_color].set_color(colors[1]) 860 elif one_color_v1 == 2: 861 xtick_labels[x_color].set_color(colors[2]) 862 elif one_color_v1 == 3: 863 xtick_labels[x_color].set_color(colors[3]) 864 elif one_color_v1 == 4: 865 xtick_labels[x_color].set_color(colors[4]) 866 elif one_color_v1 == 5: 867 xtick_labels[x_color].set_color(colors[5]) 868 elif one_color_v1 == 6: 869 xtick_labels[x_color].set_color(colors[6]) 870 elif one_color_v1 == 7: 871 xtick_labels[x_color].set_color(colors[7]) 872 elif one_color_v1 == 8: 873 xtick_labels[x_color].set_color(colors[8]) 874 elif one_color_v1 == 9: 875 xtick_labels[x_color].set_color(colors[9]) 876 # -------------------------------------------------------------------------------------- # 877 878 # 绘制双Y轴 让2个X轴一样,同时创建副坐标轴 879 ax2 = ax1.twinx() 880 881 # 图例文件描述-动态变化 882 title_up = "本月测试 " + bin_name + " 分布" 883 legend_x3 = y_name1 884 legend_x4 = y_name2 885 legend_y3 = y_name3 886 legend_y4 = y_name4 887 888 # ====================================================================================================================# 889 # 绘制柱状图 890 # bar1 = ax1.bar(bar_1_x, y_data1, label='y1轴', color='lightblue', width=0.4) 891 # bar2 = ax1.bar(bar_2_x, y_data2, label='y2轴', color='gold', width=0.4) 892 bar3 = ax1.bar(bar_1_x, y_data1, label=legend_x3, color='lightblue', width=bar_width, linewidth=0.2, edgecolor="white") 893 bar4 = ax1.bar(bar_2_x, y_data2, label=legend_x4, color='gold', width=bar_width, linewidth=0.2, edgecolor="white") 894 895 # 绘制折线图 896 # line1 = ax1.plot(x_data1, y_data1, label='y1轴', color='royalblue', marker='o', ls='-.') 897 # line2 = ax2.plot(x_data1, y_data2, label='y2轴', color='tomato', marker='o', ls='--') 898 line3 = ax2.plot(x_data1, y_data3, label=legend_y3, color='Lightgreen', marker='o', markersize='6', ls='--') 899 line4 = ax2.plot(x_data1, y_data4, label=legend_y4, color='red', marker='.', markersize='6', ls='-') 900 901 # 折线图点描述 902 for a_x1, b_y3, c_y4 in zip(x_data1, y_data3, y_data4): 903 if b_y3 < c_y4: 904 print("# 低于卡控线: ", a_x1, file=run_log) 905 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=12, font=font) 906 else: 907 # print("# 正常模组: ", a_x1) 908 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=8, font=font) 909 ax2.text(1, c_y4, '{:.2f}%'.format(c_y4 * 100), ha='center', va='bottom', fontsize=11, font=font) # 只显示一个 910 911 # ====================================================================================================================# 912 913 # 设置x轴和y轴的标签,指明坐标含义 914 ax1.set_xlabel('lot ID', fontdict={'size': 16}) 915 # 左边-y轴为:数量模式 916 ax1.set_ylabel('模组数量', fontdict={'size': 16}) 917 # 右边-y轴为:百分比形式 918 ax2.set_ylabel('百分比', fontdict={'size': 16}) 919 920 # 左-y轴为:刻度范围,动态调整 921 max_value_r1 = int(max(y_data1) * 1.3) 922 min_value_r1 = int(min(y_data1) * 0.9) 923 if max_value_r1 < 5: 924 max_value_r1 = 10 # 直接赋值 925 min_value_r1 = 0 # 直接赋值 926 ax1.set_ylim(min_value_r1, max_value_r1) 927 # 右边-y轴为:最大值为100%,小数点2位 928 ax2.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=2)) 929 930 # 设置x轴和y轴刻度字体 931 labels2 = ax2.get_xticklabels() + ax2.get_yticklabels() 932 [label.set_fontname('SimHei') for label in labels2] 933 934 # 添加图表题 plt.title('双y轴折线图') 935 plt.title(title_up, color="red", fontsize=16) 936 937 # 设置轴标签颜色 938 # ax1.tick_params('x', colors='Black') 939 ax1.tick_params('y', colors='royalblue') 940 ax2.tick_params('y', colors='tomato') 941 942 # 设置轴颜色 943 ax1.spines['left'].set_color('royalblue') 944 ax2.spines['left'].set_color('royalblue') 945 ax1.spines['right'].set_color('tomato') 946 ax2.spines['right'].set_color('tomato') 947 948 # 两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉 949 ax1.spines['top'].set_visible(False) 950 ax2.spines['top'].set_visible(False) 951 952 # 添加图例函数: plt.legend() 953 # 添加图例 - 添加方向改为以下代码 954 ax1.legend(loc='upper left') 955 ax2.legend(loc='upper right') 956 # 添加图例 - 将`图例合并改为以下代码 957 # lines = line1 + line2 + line3 + line4 958 # lines = line3 + line4 959 # labels = [h.get_label() for h in lines] 960 # plt.legend(lines, labels, loc='upper right') 961 962 # 设置中文显示 963 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体) 964 plt.rcParams['axes.unicode_minus'] = False 965 966 # 虚拟背景线 967 plt.grid(True, linestyle="--") 968 969 # 展示图片 970 # plt.show() 971 # 显示柱状图时间,单位s 972 time_v1 = 1 973 while time_v1 != 0: 974 print('显示倒计时:%d s' % time_v1) 975 plt.pause(1) 976 time_v1 = time_v1 - 1 977 print('直方图显示完成') 978 979 # 图片保存对应文件 980 picture_m = './4_result_ft/picture/' + bin_name + r".jpg" 981 plt.savefig(picture_m) 982 plt.draw() 983 print('图片保存对应文件-完成') 984 plt.close() # 关闭图表显示 985 986 987 ''' 988 # ====================================================================================================================# 989 # 本月-良品BIN1-handler&lot汇总分布-通用2模板数据处理 990 # ====================================================================================================================# 991 ''' 992 993 994 def chart_total_info(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 995 print('>>> chart_total_info ...') 996 # u1_marking, u1_handler, u1_lot, u1_input, u1_bin1, u1_bin1_p, u1_yield, name_bin, month_h1, index_s_m0, raw_data_h1 997 # 开始计时 998 datetime_object_21 = datetime.datetime.now() 999 print("datetime_object_21 :", datetime_object_21) 1000 # 1按照总数汇总 1001 # 按照handler类型汇总-4种 1002 # 按照lot类型汇总-动态 1003 x_axle_e1 = x_p1 1004 x_axle_e2 = x_p2 1005 x_axle_e3 = x_p3 1006 y_total_k1 = y_p1 1007 y_total_k2 = y_p2 1008 y_yield_k3 = y_p3 1009 y_yield_k4 = y_p4 1010 bin_name = z_p1 1011 month_u1 = z_p2 1012 single_month_g1 = z_p3 1013 raw_data_t1 = z_p4 1014 print('汇总处理: 月份< %d >' % month_u1, ) 1015 print(single_month_g1) 1016 x_name_f1, x_data_j1 = get_data_bin_v2(x_axle_e1, single_month_g1, raw_data_t1) 1017 x_name_f2, x_data_j2 = get_data_bin_v2(x_axle_e2, single_month_g1, raw_data_t1) 1018 x_name_f3, x_data_j3 = get_data_bin_v2(x_axle_e3, single_month_g1, raw_data_t1) 1019 y_name_f1, y_data_j1 = get_data_bin_v2(y_total_k1, single_month_g1, raw_data_t1) 1020 y_name_f2, y_data_j2 = get_data_bin_v2(y_total_k2, single_month_g1, raw_data_t1) 1021 y_name_f3, y_data_j3 = get_data_bin_v2(y_yield_k3, single_month_g1, raw_data_t1) 1022 y_name_f4, y_data_j4 = get_data_bin_v2(y_yield_k4, single_month_g1, raw_data_t1) 1023 # print('源1:', x_name_f1, x_data_j1) # MARKING 1024 # print('源2:', x_name_f2, x_data_j2) # HANDLER 1025 # print('源3:', x_name_f3, x_data_j3) # LOTID 1026 print('源4:', y_name_f1, y_data_j1) # Input 1027 print('源5:', y_name_f2, y_data_j2) # BIN01(Good) 1028 # print('源6:', y_name_f3, y_data_j3) # BIN01(%) 1029 # print('源7:', y_name_f4, y_data_j4) # YIELDLIMIT 1030 1031 # def limit 1032 handler_syl = 0.9000 1033 lot_syl = 0.9000 1034 1035 # 创建一个新的 Excel 文件 1036 workbook = openpyxl.Workbook() 1037 one_sheet = workbook.active 1038 test_result_v0 = ["project_name", "结果", "实际良率", "目标良率", "投入数量(ea)", "实际产出(ea)"] 1039 one_sheet.append(test_result_v0) # 追加一行数据 1040 # 动态保存路径 1041 # target_name = str(month_u1) + "月_汇总统计结果.xlsx" 1042 target_name = "月度_汇总统计结果.xlsx" 1043 target_path = r'./4_result_ft/picture/' + target_name 1044 # 保存数据 1045 # workbook.save(target_path) 1046 1047 # ---------------------------------------------------------------------------------------------------------------- # 1048 # 1按照总数汇总 1049 r1_input = np.sum(y_data_j1) 1050 r1_bin1 = np.sum(y_data_j2) 1051 r1_yield = r1_bin1 / r1_input 1052 r1_yield_percent = "{:.2%}".format(r1_yield) 1053 r1_limit = "{:.2%}".format(y_data_j4[0]) 1054 r1_state = 'pass' if r1_yield > y_data_j4[0] else 'fail' 1055 print( 1056 'summary 结果:%s 实际良率:%s 目标良率:%s 投入数量(ea): %d 实际产出(ea):%d \n' % (r1_state, r1_yield_percent, r1_limit, r1_input, r1_bin1)) 1057 1058 test_result_v0 = ["summary", r1_state, r1_yield_percent, r1_limit, r1_input, r1_bin1] 1059 one_sheet.append(test_result_v0) # 追加一行数据 1060 # ---------------------------------------------------------------------------------------------------------------- # 1061 datetime_21_1 = datetime.datetime.now() 1062 print("datetime_21_1 :", datetime_21_1, ' 耗时:', (datetime_21_1 - datetime_object_21)) 1063 # ---------------------------------------------------------------------------------------------------------------- # 1064 # 按照handler类型汇总-4种 1065 # 仅按照handler分类 顺序重新归类 1066 re_class_1 = [] 1067 re_class_2 = [] 1068 re_class_3 = [] 1069 re_class_4 = [] 1070 re_class_x = [] 1071 line_cache_a1 = [] 1072 line_cache_b1 = [] 1073 line_cache_c1 = [] 1074 line_cache_d1 = [] 1075 line_cache_x1 = [] 1076 handler_name = ["handler0 名称:", "HIP-01", "HIP-02", "HIP-03", "HIP-04", ] 1077 print("handler: ", handler_name[1:]) 1078 for handler_h1 in range(len(x_data_j2)): 1079 # print('按照handler 分组',x_data_j2[handler_h1]) 1080 if handler_name[1] == x_data_j2[handler_h1]: 1081 re_class_1.append(single_month_g1[handler_h1]) # handler1 1082 line_cache_a = [single_month_g1[handler_h1], y_data_j1[handler_h1], y_data_j2[handler_h1]] 1083 line_cache_a1.append(line_cache_a) 1084 elif handler_name[2] == x_data_j2[handler_h1]: 1085 re_class_2.append(single_month_g1[handler_h1]) # handler2 1086 line_cache_b = [single_month_g1[handler_h1], y_data_j1[handler_h1], y_data_j2[handler_h1]] 1087 line_cache_b1.append(line_cache_b) 1088 elif handler_name[3] == x_data_j2[handler_h1]: 1089 re_class_3.append(single_month_g1[handler_h1]) # handler3 1090 line_cache_c = [single_month_g1[handler_h1], y_data_j1[handler_h1], y_data_j2[handler_h1]] 1091 line_cache_c1.append(line_cache_c) 1092 elif handler_name[4] == x_data_j2[handler_h1]: 1093 re_class_4.append(single_month_g1[handler_h1]) # handler4 1094 line_cache_d = [single_month_g1[handler_h1], y_data_j1[handler_h1], y_data_j2[handler_h1]] 1095 line_cache_d1.append(line_cache_d) 1096 else: 1097 re_class_x.append(single_month_g1[handler_h1]) # handler x 1098 line_cache_x = [single_month_g1[handler_h1], y_data_j1[handler_h1], y_data_j2[handler_h1]] 1099 line_cache_x1.append(line_cache_x) 1100 1101 # 创建二维数组 1102 line_cache_s = [line_cache_a1, line_cache_b1, line_cache_c1, line_cache_d1] 1103 # 按照handler 重新分组 1104 1105 # handler_merged_4 = re_class_1 + re_class_2 + re_class_3 + re_class_4 + re_class_x 1106 # print("按照handler 重新归类 索引值: ", len(handler_merged_4), handler_merged_4) 1107 # 显示具体handler分类 1108 # print("handler1", re_class_1) 1109 # print("handler2", re_class_2) 1110 # print("handler3", re_class_3) 1111 # print("handler4", re_class_4) 1112 # print("handlerx", re_class_x) 1113 1114 # 创建handler 二维列表 实际只有4个 非常重要的列表组合创建 1115 handler_merged_5 = [re_class_1, re_class_2, re_class_3, re_class_4] 1116 # print(len(handler_merged_5), 'handler 二维列表: ', handler_merged_5) 1117 # print(len(line_cache_s) , 'handler 三维列表: ', line_cache_s) 1118 1119 # 1120 banana_a1 = [] 1121 banana_b1 = [] 1122 banana_b2 = [] 1123 banana_b3 = [] 1124 banana_b4 = [] 1125 # 根据handler列表-自动循环方案 1126 for banana in range(len(line_cache_s)): 1127 line_cache21 = [] 1128 line_cache22 = [] 1129 index_n1 = banana + 1 1130 # print("目的获取handler的个数 -第%d个 "%banana) 1131 for sub_index1 in range(len(line_cache_s[banana])): 1132 # print("目的获取三维数组的每行的列表值(一维):",line_cache_s[banana][sub_index1]) 1133 for sub_index2 in range(len(handler_merged_5)): 1134 # print('打印比对的数值:',handler_merged_5[banana][sub_index2], line_cache_s[banana][sub_index1]) 1135 if handler_merged_5[banana][sub_index2] == line_cache_s[banana][sub_index1][0]: 1136 line_cache21.append(line_cache_s[banana][sub_index1][1]) 1137 line_cache22.append(line_cache_s[banana][sub_index1][2]) 1138 h1_input = np.sum(line_cache21) 1139 h1_output = np.sum(line_cache22) 1140 h1_yield = h1_output / h1_input 1141 h1_yield_percent = "{:.2%}".format(h1_yield) 1142 h1_state = 'pass' if h1_yield > handler_syl else 'fail' 1143 print('Handler HIP-%d >>> \t结果:%s \t实际: %s \t投入数量: %d \t实际产出: %d ' % (banana, h1_state, h1_yield_percent, h1_input, h1_output,)) 1144 project_n1 = 'Handler HIP-' + str(banana) 1145 h1_syl = h1_yield_percent = "{:.2%}".format(handler_syl) 1146 test_result_v0 = [project_n1, h1_state, h1_yield, h1_syl, h1_input, h1_output] 1147 one_sheet.append(test_result_v0) # 追加一行数据 1148 1149 # 存储列表-绘图 1150 banana_a1.append(handler_name[index_n1]) 1151 banana_b1.append(h1_input) 1152 banana_b2.append(h1_output) 1153 banana_b3.append(h1_yield) 1154 banana_b4.append(handler_syl) 1155 # 绘图 1156 t_category = "handler" 1157 histogram_handle_v1_se(banana_a1, banana_b1, banana_b2, banana_b3, banana_b4, t_category) 1158 1159 # ---------------------------------------------------------------------------------------------------------------- # 1160 datetime_21_2 = datetime.datetime.now() 1161 print("datetime_21_2 :", datetime_21_2, ' 耗时:', (datetime_21_2 - datetime_21_1)) 1162 print("\n") 1163 # ---------------------------------------------------------------------------------------------------------------- # 1164 # 按照lot类型汇总-动态 1165 index_lot_lv5 = [] 1166 for orange in range(len(single_month_g1)): 1167 index_lot = single_month_g1[orange] # 获取本月行号 索引值 1168 index_m1 = x_data_j3[orange][0:6] # 获取本月行号 索引值 1169 index_lot_lv5.append(index_m1) 1170 # all raw data 有效映射 1171 # print('all raw data 有效映射: \n',index_lot_lv5) 1172 # 获取同一列表中相同元素,只保留一种类型 1173 one_lot_orange = [] 1174 for orange_lot in index_lot_lv5: 1175 if orange_lot not in one_lot_orange: 1176 one_lot_orange.append(orange_lot) 1177 print('lot 唯一代表 名称: ', one_lot_orange) 1178 1179 km_lot_all = [] 1180 for one_c1 in range(len(one_lot_orange)): 1181 km_lot = [] 1182 for watermelon in range(len(x_data_j3)): 1183 # print("Index:", one_c1, "Value:", one_lot_orange[one_c1], x_data_j3[watermelon][0:6]) 1184 if one_lot_orange[one_c1] == x_data_j3[watermelon][0:6]: 1185 # print('匹配:',one_c1 ,one_lot_orange[one_c1], x_data_j3[watermelon][0:6]) 1186 km_lot_element = [single_month_g1[watermelon], x_data_j3[watermelon], y_data_j1[watermelon], y_data_j2[watermelon]] 1187 km_lot.append(km_lot_element) 1188 # print("打印每行lot的数据:",km_lot) 1189 km_lot_all.append(km_lot) 1190 # print("打印每行lot的数据:",km_lot_all) 1191 1192 # 1193 banana_a1 = [] 1194 banana_b1 = [] 1195 banana_b2 = [] 1196 banana_b3 = [] 1197 banana_b4 = [] 1198 # 根据lot列表-自动循环方案 1199 for banana in range(len(km_lot_all)): 1200 line_cache21 = [] 1201 line_cache22 = [] 1202 # print("目的获取handler的个数 -第%d个 "%banana) 1203 for sub_index1 in range(len(km_lot_all[banana])): 1204 # print("目的获取三维数组的每行的列表值(一维):",km_lot_all[banana][sub_index1]) 1205 for sub_index2 in range(len(one_lot_orange)): 1206 # print('打印比对的数值:',one_lot_orange[sub_index2], km_lot_all[banana][sub_index1][1][0:6]) 1207 if one_lot_orange[sub_index2] == km_lot_all[banana][sub_index1][1][0:6]: 1208 line_cache21.append(km_lot_all[banana][sub_index1][2]) 1209 line_cache22.append(km_lot_all[banana][sub_index1][3]) 1210 l1_input = np.sum(line_cache21) 1211 l1_output = np.sum(line_cache22) 1212 l1_yield = l1_output / l1_input 1213 l1_yield_percent = "{:.2%}".format(l1_yield) 1214 l1_state = 'pass' if l1_yield > lot_syl else 'fail' 1215 print('lot-%s >>> \t结果%s \t良率: %s \t投入数量: %d \t实际产出: %d ' % ( 1216 km_lot_all[banana][0][1][0:6], l1_state, l1_yield_percent, l1_input, l1_output)) 1217 project_n1 = 'lot-' + km_lot_all[banana][sub_index1][1][0:6] 1218 l1_syl = "{:.2%}".format(lot_syl) 1219 test_result_v0 = [project_n1, l1_state, l1_yield_percent, l1_syl, l1_input, l1_output] 1220 one_sheet.append(test_result_v0) # 追加一行数据 1221 1222 # 存储列表-绘图 1223 banana_a1.append(one_lot_orange[banana]) 1224 banana_b1.append(l1_input) 1225 banana_b2.append(l1_output) 1226 banana_b3.append(l1_yield) 1227 banana_b4.append(lot_syl) 1228 # 绘图 1229 t_category = "lot" 1230 histogram_handle_v1_se(banana_a1, banana_b1, banana_b2, banana_b3, banana_b4, t_category) 1231 # ---------------------------------------------------------------------------------------------------------------- # 1232 datetime_21_3 = datetime.datetime.now() 1233 print("datetime_21_3 :", datetime_21_3, ' 耗时:', (datetime_21_3 - datetime_21_2)) 1234 # ---------------------------------------------------------------------------------------------------------------- # 1235 # 保存数据 1236 workbook.save(target_path) 1237 1238 datetime_object_22 = datetime.datetime.now() 1239 print("\n运行结束 :", datetime_object_22, ' 总耗时:', (datetime_object_22 - datetime_object_21)) 1240 1241 1242 ''' 1243 # ====================================================================================================================# 1244 # 本月-良品BIN1-handler&lot汇总分布-绘图2 1245 # ====================================================================================================================# 1246 ''' 1247 1248 1249 def histogram_handle_v1_se(x_p1, y_p1, y_p2, y_p3, y_p4, z_p1): 1250 print('#---- histogram_handle_v1_se ----#') 1251 x_axle_n1 = x_p1 1252 y_total_t1 = y_p1 1253 y_total_t2 = y_p2 1254 y_yield_t1 = y_p3 1255 y_yield_t2 = y_p4 1256 z_name_km1 = z_p1 1257 1258 # ======================================================================================== # 1259 # 整体参数配置 1260 font = FontProperties(size=10) 1261 plt.rcParams["font.sans-serif"] = ['SimHei'] 1262 plt.rcParams['axes.unicode_minus'] = False 1263 plt.rcParams['font.family'] = ['SimHei'] 1264 plt.rcParams['font.sans-serif'] = ['SimHei'] 1265 plt.rcParams['figure.figsize'] = (30, 10) 1266 plt.rc('font', family='SimHei', size=8) 1267 1268 # 创建一个图形和两个y轴 1269 fig, ax1 = plt.subplots(1, 1) # 绘制双Y轴 表示一次性在figure上创建成1*1的网格 1270 1271 # 柱状图柱子宽度 1272 bar_width = 0.2 1273 x_ticks = range(len(x_axle_n1)) # x轴刻度位置 | 折线图x位置 1274 bar_1_x = [(ii - bar_width + 0.1) for ii in x_ticks] # 柱状图1 - x位置 1275 bar_2_x = [(ww - bar_width + 0.3) for ww in x_ticks] 1276 1277 # 设置x轴刻度字体以及方向-单刻度标签 1278 labels1 = ax1.get_xticklabels() + ax1.get_yticklabels() 1279 [label.set_fontname('SimHei') for label in labels1] 1280 # plt.xticks(x_ticks, list(x_data1), rotation=90, ) #x轴刻度位置 | 刻度标签 | 旋转90度 1281 1282 # 设置x轴刻度字体以及方向- 叠加双刻度标签 1283 labels = [] 1284 for two_m1 in range(len(x_axle_n1)): 1285 cell_m2 = x_axle_n1[two_m1] 1286 labels.append(cell_m2) 1287 # labels = x_ticks # 默认 1288 # print('2个叠加后的刻度标签: ',labels) # 2个叠加后的刻度标签 1289 plt.xticks(x_ticks, labels, rotation=90, ) # x轴刻度位置 | 刻度标签 | 旋转90度 1290 # 自适应调整布局+ 指定 解决X轴范围问题 1291 fig.autofmt_xdate(rotation=90) 1292 1293 # -------------------------------------------------------------------------------------- # 1294 # # 同一刻度标签标记为不同颜色 插孔法 1295 # 第1种方案 1296 xtick_labels = ax1.get_xticklabels() 1297 colors = ['red', 'green', 'blue', 'purple', 'orange', 'black', 'brown', 'gray', 'pink', 'yellow', 'cyan', 'magenta'] 1298 for x_colors in range(int(len(x_axle_n1) / 4)): 1299 # print(0+x_colors*4, 1+x_colors*4, 2+x_colors*4,3+x_colors*4) 1300 x_colors_a = 0 + x_colors * 4 1301 x_colors_b = 1 + x_colors * 4 1302 x_colors_c = 2 + x_colors * 4 1303 x_colors_d = 3 + x_colors * 4 1304 xtick_labels[x_colors_a].set_color('red') 1305 xtick_labels[x_colors_b].set_color('blue') 1306 xtick_labels[x_colors_c].set_color('orange') 1307 xtick_labels[x_colors_d].set_color('magenta') 1308 1309 # -------------------------------------------------------------------------------------- # 1310 1311 # 绘制双Y轴 让2个X轴一样,同时创建副坐标轴 1312 ax2 = ax1.twinx() 1313 1314 # 图例文件描述-动态变化 1315 title_up = "本月测试 " + z_name_km1 + " 分布" 1316 legend_x3 = "input" 1317 legend_x4 = "output" 1318 legend_y3 = "yield" 1319 legend_y4 = "limit" 1320 1321 # ====================================================================================================================# 1322 # 绘制柱状图 1323 # bar1 = ax1.bar(bar_1_x, y_data1, label='y1轴', color='lightblue', width=0.4) 1324 # bar2 = ax1.bar(bar_2_x, y_data2, label='y2轴', color='gold', width=0.4) 1325 bar3 = ax1.bar(bar_1_x, y_total_t1, label=legend_x3, color='lightblue', width=bar_width, linewidth=0.2, edgecolor="white") 1326 bar4 = ax1.bar(bar_2_x, y_total_t2, label=legend_x4, color='gold', width=bar_width, linewidth=0.2, edgecolor="white") 1327 # 绘制柱描述 1328 for a, b, c in zip(bar_1_x, y_total_t1, y_total_t2): 1329 ax1.text(a - 0.1, b, '%d' % b, ha='center', va='bottom', fontsize=8, font=font, ) 1330 ax1.text(a + 0.3, c, '%d' % c, ha='center', va='bottom', fontsize=8, font=font, ) 1331 1332 # 1333 # 绘制折线图 1334 # line1 = ax1.plot(x_data1, y_data1, label='y1轴', color='royalblue', marker='o', ls='-.') 1335 # line2 = ax2.plot(x_data1, y_data2, label='y2轴', color='tomato', marker='o', ls='--') 1336 line3 = ax2.plot(x_axle_n1, y_yield_t1, label=legend_y3, color='Lightgreen', marker='o', markersize='6', ls='--') 1337 line4 = ax2.plot(x_axle_n1, y_yield_t2, label=legend_y4, color='red', marker='.', markersize='6', ls='-') 1338 1339 # 折线图点描述 1340 for a_x1, b_y3, c_y4 in zip(x_axle_n1, y_yield_t1, y_yield_t2): 1341 if b_y3 < c_y4: 1342 print("# 低于卡控线: ", a_x1, file=run_log) 1343 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=12, font=font) 1344 else: 1345 # print("# 正常模组: ", a_x1) 1346 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=8, font=font) 1347 ax2.text(1, c_y4, '{:.2f}%'.format(c_y4 * 100), ha='center', va='bottom', fontsize=11, font=font) # 只显示一个 1348 1349 # ====================================================================================================================# 1350 1351 # 设置x轴和y轴的标签,指明坐标含义 1352 ax1.set_xlabel(z_name_km1, fontdict={'size': 16}) 1353 # 左边-y轴为:数量模式 1354 ax1.set_ylabel('模组数量', fontdict={'size': 16}) 1355 # 右边-y轴为:百分比形式 1356 ax2.set_ylabel('百分比', fontdict={'size': 16}) 1357 1358 # 左-y轴为:刻度范围,动态调整 1359 max_value_r1 = int(max(y_total_t1) * 1.3) 1360 min_value_r1 = int(min(y_total_t2) * 0.9) 1361 if max_value_r1 < 5: 1362 max_value_r1 = 10 # 直接赋值 1363 min_value_r1 = 0 # 直接赋值 1364 ax1.set_ylim(min_value_r1, max_value_r1) 1365 # 右边-y轴为:最大值为100%,小数点2位 1366 ax2.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=2)) 1367 1368 # 设置x轴和y轴刻度字体 1369 labels2 = ax2.get_xticklabels() + ax2.get_yticklabels() 1370 [label.set_fontname('SimHei') for label in labels2] 1371 1372 # 添加图表题 plt.title('双y轴折线图') 1373 plt.title(title_up, color="red", fontsize=16) 1374 1375 # 设置轴标签颜色 1376 # ax1.tick_params('x', colors='Black') 1377 ax1.tick_params('y', colors='royalblue') 1378 ax2.tick_params('y', colors='tomato') 1379 1380 # 设置轴颜色 1381 ax1.spines['left'].set_color('royalblue') 1382 ax2.spines['left'].set_color('royalblue') 1383 ax1.spines['right'].set_color('tomato') 1384 ax2.spines['right'].set_color('tomato') 1385 1386 # 两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉 1387 ax1.spines['top'].set_visible(False) 1388 ax2.spines['top'].set_visible(False) 1389 1390 # 添加图例函数: plt.legend() 1391 # 添加图例 - 添加方向改为以下代码 1392 ax1.legend(loc='upper left') 1393 ax2.legend(loc='upper right') 1394 # 添加图例 - 将`图例合并改为以下代码 1395 # lines = line1 + line2 + line3 + line4 1396 # lines = line3 + line4 1397 # labels = [h.get_label() for h in lines] 1398 # plt.legend(lines, labels, loc='upper right') 1399 1400 # 设置中文显示 1401 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体) 1402 plt.rcParams['axes.unicode_minus'] = False 1403 1404 # 虚拟背景线 1405 plt.grid(True, linestyle="--") 1406 1407 # 展示图片 1408 # plt.show() 1409 # 显示柱状图时间,单位s 1410 time_v1 = 1 1411 while time_v1 != 0: 1412 print('显示倒计时:%d s' % time_v1) 1413 plt.pause(1) 1414 time_v1 = time_v1 - 1 1415 print('直方图显示完成') 1416 1417 # 图片保存对应文件 1418 picture_m = './4_result_ft/picture/' + z_name_km1 + r".jpg" 1419 plt.savefig(picture_m) 1420 plt.draw() 1421 print('图片保存对应文件-完成') 1422 plt.close() # 关闭图表显示 1423 1424 1425 ''' 1426 # ====================================================================================================================# 1427 # 本月测试BIN数据 显示所有头文件名称 1428 # ====================================================================================================================# 1429 ''' 1430 1431 1432 def display_all_header_file_names(x_p1, z_p1, z_p2): 1433 # 指定月份 - 归类前文件 1434 marking_nb = x_p1 1435 single_month_data = z_p1 1436 all_month_raw_data = z_p2 1437 c_g_name1, c_g_data1 = get_data_bin_v2(marking_nb, single_month_data, all_month_raw_data) 1438 print("指定文件名称:", c_g_name1, c_g_data1) 1439 1440 1441 ''' 1442 # ====================================================================================================================# 1443 # 本月-良品BIN1-测试数据汇总分布-通用模板1数据处理 1444 # ====================================================================================================================# 1445 ''' 1446 1447 1448 def defective_reorder_sub(x_p1, x_p2, x_p3, z_p1, z_p2, z_p3, z_p4): 1449 # ---------------------------------------------------------------------------------------------------------------- # 1450 # 开始计时 1451 datetime_object_11 = datetime.datetime.now() 1452 print("datetime_object_11 :", datetime_object_11) 1453 1454 # 使用无表头,使用数字强制索引 -- 第一份引用 1455 x_handler_n2 = x_p2 1456 x_lot_n3 = x_p3 1457 month_n2 = z_p2 1458 single_month_d2 = z_p3 1459 raw_data_a2 = z_p4 1460 1461 # ---------------------------------------------------------------------------------------------------------------------- # 1462 # 处理1 数据归类 1463 print('指定月份 - 归类前文件: 月份< %d >' % month_n2, z_p1) 1464 1465 # 指定月份 - 归类前文件 1466 c_g_name1, c_g_data1 = get_data_bin_v2(x_lot_n3, single_month_d2, raw_data_a2) 1467 c_g_name2, c_g_data2 = get_data_bin_v2(x_handler_n2, single_month_d2, raw_data_a2) 1468 # print("源1:", c_g_name1, c_g_data1) 1469 # print("源2:", c_g_name2, c_g_data2) 1470 1471 # ---------------------------------------------------------------------------------------------------------------- # 1472 lot_list_v1 = [] 1473 lot_list_v3 = [] 1474 for index_a in range(len(c_g_data1)): 1475 num_v1_lot = single_month_d2[index_a] # 获取本月行号 索引值 1476 str_v1_lot = c_g_data1[index_a][0:6] # 正则表达获取lot ,去除wafer 1477 lot_handler_t1 = c_g_data2[index_a] # 获取附属信息 handler 1478 lot_list_v2 = [num_v1_lot, str_v1_lot, lot_handler_t1] # 3个关键字存储到一维列表中 1479 lot_list_v1.append(lot_list_v2) # 存储到一维列表到二维列表中 1480 lot_list_v3.append(str_v1_lot) # 1个关键字存储到一维列表中 1481 # all raw data 有效映射 1482 # print('all data -- 切片lot : ', len(lot_list_v1), lot_list_v1) 1483 1484 # 获取同一列表中相同元素,只保留一种类型 1485 one_lot = [] 1486 for v2_lot in lot_list_v3: 1487 if v2_lot not in one_lot: 1488 one_lot.append(v2_lot) 1489 print('lot中唯一代表名称: ', one_lot) 1490 1491 # 先按照 lot 分类 再按照 handler分类 最后索引-行号 1492 lot_handler_m1 = [] # 重新分类聚合的列表 1493 lot_h1_m1 = [] 1494 lot_h1_m2 = [] 1495 # 先按照 lot 大类分组 1496 for row_v1_w1 in one_lot: 1497 # print('每种类型的lot: ',row_v1_w1) 1498 line_re_lot5 = [] 1499 1500 for row_v1 in lot_list_v1: 1501 # print('切片lot中第1个元素-二维列中每行第1个元素: ',row_v1[1]) 1502 if row_v1_w1 == row_v1[1]: 1503 # print('打印相同的元素名称: ',row_v1_w1,row_v1[0],row_v1[1]) 1504 line_re_lot4 = [row_v1[0], row_v1[1], row_v1[2]] # 按照每个lot大类重新组合索引值 1505 line_re_lot5.append(line_re_lot4) 1506 lot_h1_m1.append(row_v1[0]) 1507 lot_h1_m2.append(line_re_lot4) 1508 # print('每个lot大类-组合: ',line_re_lot5) 1509 1510 # 每个lot类 再按照 handler 重新分类 1511 re_handler_1 = [] 1512 re_handler_2 = [] 1513 re_handler_3 = [] 1514 re_handler_4 = [] 1515 re_handler_x = [] 1516 handler_name_d = ["handler0 名称:", "HIP-01", "HIP-02", "HIP-03", "HIP-04", ] # TODO g根据机台重新添加 1517 for two_m1 in line_re_lot5: 1518 # print('每个lot中 handler元素组合:',two_m1,two_m1[2]) 1519 if handler_name_d[1] == two_m1[2]: 1520 # print('具体handler匹配: ',handler_name_d[1],two_m1[2]) 1521 re_handler_1.append(two_m1[0]) # handler1 1522 elif handler_name_d[2] == two_m1[2]: 1523 re_handler_2.append(two_m1[0]) # handler2 1524 elif handler_name_d[3] == two_m1[2]: 1525 re_handler_3.append(two_m1[0]) # handler3 1526 elif handler_name_d[4] == two_m1[2]: 1527 re_handler_4.append(two_m1[0]) # handler4 1528 else: 1529 re_handler_x.append(two_m1[0]) # handler x 未知分类 1530 1531 # 一维列表合并 1532 re_handler_m = re_handler_1 + re_handler_2 + re_handler_3 + re_handler_4 + re_handler_x 1533 # print("按照handler 子归类:", re_handler_m) 1534 lot_handler_m1.append(re_handler_m) # 一维列表组合成二维列表 1535 # ---------------------------------------------------------------------------------------------------------------- # 1536 # 显示分组情况 1537 # 第1种情况 1538 # print('仅按照大类lot分组:',len(lot_h1_m2),lot_h1_m2) 1539 # print('仅按照大类lot分组-索引行号:', len(lot_h1_m1), lot_h1_m1) 1540 1541 # 第2种情况 1542 # print("lot_handler_ 分组二维列表:", len(lot_handler_m1), lot_handler_m1) 1543 # 二维列表转一维列表 非常重要 1544 lot_handler_m1_result = [n for a in lot_handler_m1 for n in a] 1545 print('最终结果 -- lot_handler_m1_result: ', lot_handler_m1_result) 1546 1547 # # 第3种情况 - 仅仅按照handler分类 顺序重新归类 1548 # reclassify_1 = [] 1549 # reclassify_2 = [] 1550 # reclassify_3 = [] 1551 # reclassify_4 = [] 1552 # reclassify_x = [] 1553 # handler_name = ["handler0 名称:", "HIP-01", "HIP-02", "HIP-03", "HIP-04", ] 1554 # for two_m1 in range(len(single_month_m12[month_h1])): 1555 # # print('按照handler 分组',single_month_m12[month_h1][two_m1]) 1556 # if handler_name[1] == c_g_data2[two_m1]: 1557 # reclassify_1.append(single_month_m12[month_h1][two_m1]) # handler1 1558 # elif handler_name[2] == c_g_data2[two_m1]: 1559 # reclassify_2.append(single_month_m12[month_h1][two_m1]) # handler2 1560 # elif handler_name[3] == c_g_data2[two_m1]: 1561 # reclassify_3.append(single_month_m12[month_h1][two_m1]) # handler3 1562 # elif handler_name[4] == c_g_data2[two_m1]: 1563 # reclassify_4.append(single_month_m12[month_h1][two_m1]) # handler4 1564 # else: 1565 # reclassify_x.append(single_month_m12[month_h1][two_m1]) # handler x 1566 # handler_merged_result3 = reclassify_1 + reclassify_2 + reclassify_3 + reclassify_4 + reclassify_x 1567 # print("按照handler 重新归类 索引值: ",handler_merged_result3) 1568 1569 # 用目标值 替换源列表中 行分组 1570 single_month_d2 = lot_handler_m1_result 1571 # single_month_m12[month_h1] = handler_merged_result3 1572 # 显示新月份所有的月度索引值-行号 1573 # for index_a in range(1, 13): 1574 # print('第%d月数据' % (index_a), single_month_m12[index_a]) 1575 # 新索引值重新被引用 1576 index_s_m2 = single_month_d2 1577 1578 datetime_object_12 = datetime.datetime.now() 1579 print("datetime_object_12 :", datetime_object_12, ' 耗时:', (datetime_object_12 - datetime_object_11)) 1580 1581 # ---------------------------------------------------------------------------------------------------------------------- # 1582 return index_s_m2 1583 1584 1585 ''' 1586 # ====================================================================================================================# 1587 # 本月 --- 不良品BIN --- 测试数据汇总分布-通用模板2数据处理 1588 # ====================================================================================================================# 1589 ''' 1590 1591 1592 def defective_handle_v2(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 1593 print("#**** handle_v2_pro ****# >>> ", z_p1) 1594 # 按照 仅handler-marking 分类 1595 # 按照 仅lot-marking 分类 1596 # 按照 lot - handler - marking 分类 1597 single_month_z2 = defective_reorder_sub(x_p1, x_p2, x_p3, z_p1, z_p2, z_p3, z_p4) 1598 # 按照 handler - lot - marking 分类 1599 # 按照 summary表-marking 顺序 1600 1601 # 重新赋值 -single month raw data index 1602 x_axle_n1 = x_p1 1603 x_axle_n2 = x_p2 1604 x_axle_n3 = x_p3 1605 y_total_t1 = y_p1 1606 y_total_t2 = y_p2 1607 y_yield_t1 = y_p3 1608 y_yield_t2 = y_p4 1609 bin_name = z_p1 1610 month_n1 = z_p2 1611 single_month_d1 = single_month_z2 1612 raw_data_a1 = z_p4 1613 print('绘图处理: 月份< %d > 不良品< %s >' % (month_n1, bin_name)) 1614 # 获取每月函数 有效数据 x_axle_n2 1615 x_name1, x_data1 = get_data_bin_v2(x_axle_n1, single_month_d1, raw_data_a1) 1616 x_name2, x_data2 = get_data_bin_v2(x_axle_n2, single_month_d1, raw_data_a1) 1617 x_name3, x_data3 = get_data_bin_v2(x_axle_n3, single_month_d1, raw_data_a1) 1618 y_name1, y_data1 = get_data_bin_v2(y_total_t1, single_month_d1, raw_data_a1) 1619 y_name2, y_data2 = get_data_bin_v2(y_total_t2, single_month_d1, raw_data_a1) 1620 y_name3, y_data3 = get_data_bin_v2(y_yield_t1, single_month_d1, raw_data_a1) 1621 y_name4, y_data4 = get_data_bin_v2(y_yield_t2, single_month_d1, raw_data_a1) 1622 # print(x_name1, x_data1) 1623 # print(x_name2, x_data2) 1624 # print(y_name1, y_data1) 1625 # print(y_name2, y_data2) 1626 # print(y_name3, y_data3) 1627 1628 # ======================================================================================== # 1629 1630 # 整体参数配置 1631 font = FontProperties(size=10) 1632 plt.rcParams["font.sans-serif"] = ['SimHei'] 1633 plt.rcParams['axes.unicode_minus'] = False 1634 plt.rcParams['font.family'] = ['SimHei'] 1635 plt.rcParams['font.sans-serif'] = ['SimHei'] 1636 plt.rcParams['figure.figsize'] = (30, 10) 1637 plt.rc('font', family='SimHei', size=8) 1638 1639 # 创建一个图形和两个y轴 1640 fig, ax1 = plt.subplots(1, 1) # 绘制双Y轴 表示一次性在figure上创建成1*1的网格 1641 1642 # 柱状图柱子宽度 1643 bar_width = 0.4 1644 x_ticks = range(len(x_data1)) # x轴刻度位置 | 折线图x位置 1645 bar_1_x = [(ii - bar_width + 0.2) for ii in x_ticks] # 柱状图1 - x位置 1646 bar_2_x = [(ww - bar_width + 0.6) for ww in x_ticks] 1647 1648 # 设置x轴刻度字体以及方向-单刻度标签 1649 labels1 = ax1.get_xticklabels() + ax1.get_yticklabels() 1650 [label.set_fontname('SimHei') for label in labels1] 1651 # plt.xticks(x_ticks, list(x_data1), rotation=90, ) #x轴刻度位置 | 刻度标签 | 旋转90度 1652 1653 # 设置x轴刻度字体以及方向- 叠加双刻度标签 1654 labels = [] 1655 for two_m1 in range(len(x_data1)): 1656 cell_m2 = x_data3[two_m1][0:6] + ' ' + x_data2[two_m1] + ' ' + x_data1[two_m1] 1657 labels.append(cell_m2) 1658 # labels = x_ticks # 默认 1659 # print('2个叠加后的刻度标签: ',labels) # 2个叠加后的刻度标签 1660 plt.xticks(x_ticks, labels, rotation=90, ) # x轴刻度位置 | 刻度标签 | 旋转90度 1661 # 自适应调整布局+ 指定 解决X轴范围问题 1662 fig.autofmt_xdate(rotation=90) 1663 1664 # -------------------------------------------------------------------------------------- # 1665 # # 同一刻度标签标记为不同颜色 插孔法 升级-适用较为复杂的场景 第2种方案 1666 index_lot_v5 = [] 1667 for index_a in range(len(single_month_d1)): 1668 index_lot = single_month_d1[index_a] # 获取本月行号 索引值 1669 index_m1 = x_data3[index_a][0:6] # 获取本月行号 索引值 1670 index_lot_v5.append(index_m1) 1671 # all raw data 有效映射 1672 # print("all raw data 有效映射:", index_lot_v5) 1673 # 获取同一列表中相同元素,只保留一种类型 1674 one_lot_v1 = [] 1675 for v2_lot in index_lot_v5: 1676 if v2_lot not in one_lot_v1: 1677 one_lot_v1.append(v2_lot) 1678 # print('lot中唯一代表名称: ', one_lot_v1) 1679 xtick_labels = ax1.get_xticklabels() 1680 colors = ['red', 'green', 'blue', 'purple', 'orange', 'brown', 'gray', 'pink', 'cyan', 'magenta', 'yellow', 'black', ] 1681 # 利用唯一lot去适配列表lot,影射到对应刻度,根据余数去自动识别颜色,默认10种 1682 for x_color in range(len(x_data3)): 1683 # print("x_color: ",x_color,x_data3[x_color][0:6]) 1684 for one_c1 in range(len(one_lot_v1)): 1685 # print("Index:", one_c1, "Value:", one_lot_v1[one_c1]) 1686 if one_lot_v1[one_c1] == x_data3[x_color][0:6]: 1687 one_color_v1 = one_c1 % 10 1688 if one_color_v1 == 0: 1689 xtick_labels[x_color].set_color(colors[0]) 1690 elif one_color_v1 == 1: 1691 xtick_labels[x_color].set_color(colors[1]) 1692 elif one_color_v1 == 2: 1693 xtick_labels[x_color].set_color(colors[2]) 1694 elif one_color_v1 == 3: 1695 xtick_labels[x_color].set_color(colors[3]) 1696 elif one_color_v1 == 4: 1697 xtick_labels[x_color].set_color(colors[4]) 1698 elif one_color_v1 == 5: 1699 xtick_labels[x_color].set_color(colors[5]) 1700 elif one_color_v1 == 6: 1701 xtick_labels[x_color].set_color(colors[6]) 1702 elif one_color_v1 == 7: 1703 xtick_labels[x_color].set_color(colors[7]) 1704 elif one_color_v1 == 8: 1705 xtick_labels[x_color].set_color(colors[8]) 1706 elif one_color_v1 == 9: 1707 xtick_labels[x_color].set_color(colors[9]) 1708 # -------------------------------------------------------------------------------------- # 1709 1710 # 绘制双Y轴 让2个X轴一样,同时创建副坐标轴 1711 ax2 = ax1.twinx() 1712 1713 # 图例文件描述-动态变化 1714 title_up = "本月测试 " + bin_name + " 分布" 1715 legend_x3 = y_name1 1716 legend_x4 = y_name2 1717 legend_y3 = y_name3 1718 legend_y4 = y_name4 1719 1720 # ====================================================================================================================# 1721 # 绘制柱状图 1722 # bar1 = ax1.bar(bar_1_x, y_data1, label='y1轴', color='lightblue', width=0.4) 1723 # bar2 = ax1.bar(bar_2_x, y_data2, label='y2轴', color='gold', width=0.4) 1724 bar3 = ax1.bar(bar_1_x, y_data1, label=legend_x3, color='lightblue', width=bar_width, linewidth=0.2, edgecolor="white") 1725 bar4 = ax1.bar(bar_2_x, y_data2, label=legend_x4, color='gold', width=bar_width, linewidth=0.2, edgecolor="white") 1726 1727 # 绘制折线图 1728 # line1 = ax1.plot(x_data1, y_data1, label='y1轴', color='royalblue', marker='o', ls='-.') 1729 # line2 = ax2.plot(x_data1, y_data2, label='y2轴', color='tomato', marker='o', ls='--') 1730 line3 = ax2.plot(x_data1, y_data3, label=legend_y3, color='Lightgreen', marker='o', markersize='6', ls='--') 1731 line4 = ax2.plot(x_data1, y_data4, label=legend_y4, color='royalblue', marker='.', markersize='6', ls='-') 1732 1733 # ------------------------------------------------------------------------------------------------------------------- # 1734 # #TODO <特殊情况处理 -20231211> 1735 # ------------------------------------------------------------------------------------------------------------------- # 1736 legend_y5 = "sbl" # 新增sbl 卡控图例名称 1737 1738 if bin_name == "BIN3": 1739 y_data5 = [] 1740 sbl_data = 0.003 1741 for sbl_avocado in range(len(y_data4)): 1742 y_data5.append(sbl_data) 1743 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1744 # 折线图点描述 1745 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1746 if b_y3 < b_y4: 1747 print("# BIN3 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1748 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1749 if b_y4 > c_y5: 1750 print("# BIN3 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1751 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1752 # 只显示一个 sbl 1753 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1754 1755 elif bin_name == "BIN4": 1756 y_data5 = [] 1757 sbl_data = 0.0001 1758 for sbl_avocado in range(len(y_data4)): 1759 y_data5.append(sbl_data) 1760 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1761 # 折线图点描述 1762 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1763 if b_y3 < b_y4: 1764 print("# BIN4 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1765 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1766 if b_y4 > c_y5: 1767 print("# BIN4 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1768 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1769 # 只显示一个 sbl 1770 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1771 1772 elif bin_name == "BIN5": 1773 y_data5 = [] 1774 sbl_data = 0.0193 1775 for sbl_avocado in range(len(y_data4)): 1776 y_data5.append(sbl_data) 1777 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1778 # 折线图点描述 1779 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1780 if b_y3 < b_y4: 1781 print("# BIN5 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1782 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1783 if b_y4 > c_y5: 1784 print("# BIN5 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1785 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1786 # 只显示一个 sbl 1787 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1788 1789 elif bin_name == "BIN6_1": 1790 y_data5 = [] 1791 sbl_data = 0.0204 1792 for sbl_avocado in range(len(y_data4)): 1793 y_data5.append(sbl_data) 1794 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1795 # 折线图点描述 1796 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1797 if b_y3 < b_y4: 1798 print("# BIN6_1 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1799 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1800 if b_y4 > c_y5: 1801 print("# BIN6_1 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1802 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1803 # 只显示一个 sbl 1804 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1805 1806 elif bin_name == "BIN6_2": 1807 y_data5 = [] 1808 sbl_data = 0.0193 1809 for sbl_avocado in range(len(y_data4)): 1810 y_data5.append(sbl_data) 1811 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1812 # 折线图点描述 1813 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1814 if b_y3 < b_y4: 1815 print("# BIN6_2 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1816 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1817 if b_y4 > c_y5: 1818 print("# BIN6_2 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1819 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1820 # 只显示一个 sbl 1821 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1822 1823 elif bin_name == "BIN7_1": 1824 y_data5 = [] 1825 sbl_data = 0.0100 1826 for sbl_avocado in range(len(y_data4)): 1827 y_data5.append(sbl_data) 1828 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1829 # 折线图点描述 1830 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1831 if b_y3 < b_y4: 1832 print("# BIN7_1 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1833 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1834 if b_y4 > c_y5: 1835 print("# BIN7_1 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1836 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1837 # 只显示一个 sbl 1838 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1839 1840 elif bin_name == "BIN7_2": 1841 y_data5 = [] 1842 sbl_data = 0.001 1843 for sbl_avocado in range(len(y_data4)): 1844 y_data5.append(sbl_data) 1845 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1846 # 折线图点描述 1847 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1848 if b_y3 < b_y4: 1849 print("# BIN7_2 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1850 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1851 if b_y4 > c_y5: 1852 print("# BIN7_2 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1853 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1854 # 只显示一个 sbl 1855 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1856 1857 elif bin_name == "BIN7_3": 1858 y_data5 = [] 1859 sbl_data = 0.0001 1860 for sbl_avocado in range(len(y_data4)): 1861 y_data5.append(sbl_data) 1862 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 1863 # 折线图点描述 1864 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 1865 if b_y3 < b_y4: 1866 print("# BIN7_3 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log) 1867 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1868 if b_y4 > c_y5: 1869 print("# BIN7_3 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log) 1870 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 1871 # 只显示一个 sbl 1872 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 1873 else: 1874 print("无符合case 的 bin") 1875 # 1876 # ====================================================================================================================# 1877 1878 # 设置x轴和y轴的标签,指明坐标含义 1879 ax1.set_xlabel('lot ID', fontdict={'size': 16}) 1880 # 左边-y轴为:数量模式 1881 ax1.set_ylabel('模组数量', fontdict={'size': 16}) 1882 # 右边-y轴为:百分比形式 1883 ax2.set_ylabel('百分比', fontdict={'size': 16}) 1884 1885 # 左-y轴为:刻度范围,动态调整 1886 max_value_r1 = int(max(y_data1) * 1.3) 1887 min_value_r1 = int(min(y_data1) * 0.9) 1888 if max_value_r1 < 5: 1889 max_value_r1 = 10 # 直接赋值 1890 min_value_r1 = 0 # 直接赋值 1891 ax1.set_ylim(min_value_r1, max_value_r1) 1892 # 右边-y轴为:最大值为100%,小数点2位 1893 ax2.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=2)) 1894 1895 # 设置x轴和y轴刻度字体 1896 labels2 = ax2.get_xticklabels() + ax2.get_yticklabels() 1897 [label.set_fontname('SimHei') for label in labels2] 1898 1899 # 添加图表题 plt.title('双y轴折线图') 1900 plt.title(title_up, color="red", fontsize=16) 1901 1902 # 设置轴标签颜色 1903 # ax1.tick_params('x', colors='Black') 1904 ax1.tick_params('y', colors='royalblue') 1905 ax2.tick_params('y', colors='tomato') 1906 1907 # 设置轴颜色 1908 ax1.spines['left'].set_color('royalblue') 1909 ax2.spines['left'].set_color('royalblue') 1910 ax1.spines['right'].set_color('tomato') 1911 ax2.spines['right'].set_color('tomato') 1912 1913 # 两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉 1914 ax1.spines['top'].set_visible(False) 1915 ax2.spines['top'].set_visible(False) 1916 1917 # 添加图例函数: plt.legend() 1918 # 添加图例 - 添加方向改为以下代码 1919 ax1.legend(loc='upper left') 1920 ax2.legend(loc='upper right') 1921 # 添加图例 - 将`图例合并改为以下代码 1922 # lines = line1 + line2 + line3 + line4 1923 # lines = line3 + line4 1924 # labels = [h.get_label() for h in lines] 1925 # plt.legend(lines, labels, loc='upper right') 1926 1927 # 设置中文显示 1928 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体) 1929 plt.rcParams['axes.unicode_minus'] = False 1930 1931 # 虚拟背景线 1932 plt.grid(True, linestyle="--") 1933 1934 # 展示图片 1935 # plt.show() 1936 # 显示柱状图时间,单位s 1937 time_v1 = 1 1938 while time_v1 != 0: 1939 print('显示倒计时:%d s' % time_v1) 1940 plt.pause(1) 1941 time_v1 = time_v1 - 1 1942 print('直方图显示完成') 1943 1944 # 图片保存对应文件 1945 picture_m = './4_result_ft/picture/' + bin_name + r".jpg" 1946 plt.savefig(picture_m) 1947 plt.draw() 1948 print('图片保存对应文件-完成') 1949 plt.close() # 关闭图表显示 1950 1951 1952 ''' 1953 # ====================================================================================================================# 1954 # 本月 --- 不良品BIN --- 测试数据汇总分布-通用模板2_se数据处理 1955 # ====================================================================================================================# 1956 ''' 1957 1958 1959 def defective_handle_v2_se(x_p1, x_p2, x_p3, y_p1, y_p3, z_p1, z_p2, z_p3, z_p4): 1960 print("#**** handle_v2_pro ****# >>> ", z_p1) 1961 # 按照 仅handler-marking 分类 1962 # 按照 仅lot-marking 分类 1963 # 按照 lot - handler - marking 分类 1964 single_month_z2 = defective_reorder_sub(x_p1, x_p2, x_p3, z_p1, z_p2, z_p3, z_p4) 1965 # 按照 handler - lot - marking 分类 1966 # 按照 summary表-marking 顺序 1967 1968 # 重新赋值 -single month raw data index 1969 x_axle_n1 = x_p1 1970 x_axle_n2 = x_p2 1971 x_axle_n3 = x_p3 1972 y_total_t1 = y_p1 1973 y_yield_t1 = y_p3 1974 bin_name = z_p1 1975 month_n1 = z_p2 1976 single_month_d1 = single_month_z2 1977 raw_data_a1 = z_p4 1978 print('绘图处理: 月份< %d > 不良品< %s >' % (month_n1, bin_name)) 1979 # 获取每月函数 有效数据 x_axle_n2 1980 x_name1, x_data1 = get_data_bin_v2(x_axle_n1, single_month_d1, raw_data_a1) 1981 x_name2, x_data2 = get_data_bin_v2(x_axle_n2, single_month_d1, raw_data_a1) 1982 x_name3, x_data3 = get_data_bin_v2(x_axle_n3, single_month_d1, raw_data_a1) 1983 y_name1, y_data1 = get_data_bin_v2(y_total_t1, single_month_d1, raw_data_a1) 1984 y_name3, y_data3 = get_data_bin_v2(y_yield_t1, single_month_d1, raw_data_a1) 1985 # print(x_name1, x_data1) 1986 # print(x_name2, x_data2) 1987 # print(y_name1, y_data1) 1988 # print(y_name2, y_data2) 1989 # print(y_name3, y_data3) 1990 1991 # ======================================================================================== # 1992 1993 # 整体参数配置 1994 font = FontProperties(size=10) 1995 plt.rcParams["font.sans-serif"] = ['SimHei'] 1996 plt.rcParams['axes.unicode_minus'] = False 1997 plt.rcParams['font.family'] = ['SimHei'] 1998 plt.rcParams['font.sans-serif'] = ['SimHei'] 1999 plt.rcParams['figure.figsize'] = (30, 10) 2000 plt.rc('font', family='SimHei', size=8) 2001 2002 # 创建一个图形和两个y轴 2003 fig, ax1 = plt.subplots(1, 1) # 绘制双Y轴 表示一次性在figure上创建成1*1的网格 2004 2005 # 柱状图柱子宽度 2006 bar_width = 0.4 2007 x_ticks = range(len(x_data1)) # x轴刻度位置 | 折线图x位置 2008 bar_1_x = [(ii - bar_width + 0.2) for ii in x_ticks] # 柱状图1 - x位置 2009 bar_2_x = [(ww - bar_width + 0.6) for ww in x_ticks] 2010 2011 # 设置x轴刻度字体以及方向-单刻度标签 2012 labels1 = ax1.get_xticklabels() + ax1.get_yticklabels() 2013 [label.set_fontname('SimHei') for label in labels1] 2014 # plt.xticks(x_ticks, list(x_data1), rotation=90, ) #x轴刻度位置 | 刻度标签 | 旋转90度 2015 2016 # 设置x轴刻度字体以及方向- 叠加双刻度标签 2017 labels = [] 2018 for two_m1 in range(len(x_data1)): 2019 cell_m2 = x_data3[two_m1][0:6] + ' ' + x_data2[two_m1] + ' ' + x_data1[two_m1] 2020 labels.append(cell_m2) 2021 # labels = x_ticks # 默认 2022 # print('2个叠加后的刻度标签: ',labels) # 2个叠加后的刻度标签 2023 plt.xticks(x_ticks, labels, rotation=90, ) # x轴刻度位置 | 刻度标签 | 旋转90度 2024 # 自适应调整布局+ 指定 解决X轴范围问题 2025 fig.autofmt_xdate(rotation=90) 2026 2027 # -------------------------------------------------------------------------------------- # 2028 # # 同一刻度标签标记为不同颜色 插孔法 升级-适用较为复杂的场景 第2种方案 2029 index_lot_v5 = [] 2030 for index_a in range(len(single_month_d1)): 2031 index_lot = single_month_d1[index_a] # 获取本月行号 索引值 2032 index_m1 = x_data3[index_a][0:6] # 获取本月行号 索引值 2033 index_lot_v5.append(index_m1) 2034 # all raw data 有效映射 2035 print("all raw data 有效映射:", index_lot_v5) 2036 # 获取同一列表中相同元素,只保留一种类型 2037 one_lot_v1 = [] 2038 for v2_lot in index_lot_v5: 2039 if v2_lot not in one_lot_v1: 2040 one_lot_v1.append(v2_lot) 2041 print('lot中唯一代表名称: ', one_lot_v1) 2042 xtick_labels = ax1.get_xticklabels() 2043 colors = ['red', 'green', 'blue', 'purple', 'orange', 'brown', 'gray', 'pink', 'cyan', 'magenta', 'yellow', 'black', ] 2044 # 利用唯一lot去适配列表lot,影射到对应刻度,根据余数去自动识别颜色,默认10种 2045 for x_color in range(len(x_data3)): 2046 # print("x_color: ",x_color,x_data3[x_color][0:6]) 2047 for one_c1 in range(len(one_lot_v1)): 2048 # print("Index:", one_c1, "Value:", one_lot_v1[one_c1]) 2049 if one_lot_v1[one_c1] == x_data3[x_color][0:6]: 2050 one_color_v1 = one_c1 % 10 2051 if one_color_v1 == 0: 2052 xtick_labels[x_color].set_color(colors[0]) 2053 elif one_color_v1 == 1: 2054 xtick_labels[x_color].set_color(colors[1]) 2055 elif one_color_v1 == 2: 2056 xtick_labels[x_color].set_color(colors[2]) 2057 elif one_color_v1 == 3: 2058 xtick_labels[x_color].set_color(colors[3]) 2059 elif one_color_v1 == 4: 2060 xtick_labels[x_color].set_color(colors[4]) 2061 elif one_color_v1 == 5: 2062 xtick_labels[x_color].set_color(colors[5]) 2063 elif one_color_v1 == 6: 2064 xtick_labels[x_color].set_color(colors[6]) 2065 elif one_color_v1 == 7: 2066 xtick_labels[x_color].set_color(colors[7]) 2067 elif one_color_v1 == 8: 2068 xtick_labels[x_color].set_color(colors[8]) 2069 elif one_color_v1 == 9: 2070 xtick_labels[x_color].set_color(colors[9]) 2071 # -------------------------------------------------------------------------------------- # 2072 2073 # 绘制双Y轴 让2个X轴一样,同时创建副坐标轴 2074 ax2 = ax1.twinx() 2075 2076 # 图例文件描述-动态变化 2077 title_up = "本月测试 " + bin_name + " 分布" 2078 legend_x3 = y_name1 2079 legend_y3 = y_name3 2080 2081 # ====================================================================================================================# 2082 # 绘制柱状图 2083 # bar1 = ax1.bar(bar_1_x, y_data1, label='y1轴', color='lightblue', width=0.4) 2084 # bar2 = ax1.bar(bar_2_x, y_data2, label='y2轴', color='gold', width=0.4) 2085 bar3 = ax1.bar(bar_1_x, y_data1, label=legend_x3, color='lightblue', width=bar_width, linewidth=0.2, edgecolor="white") 2086 2087 # 绘制折线图 2088 # line1 = ax1.plot(x_data1, y_data1, label='y1轴', color='royalblue', marker='o', ls='-.') 2089 # line2 = ax2.plot(x_data1, y_data2, label='y2轴', color='tomato', marker='o', ls='--') 2090 line3 = ax2.plot(x_data1, y_data3, label=legend_y3, color='Lightgreen', marker='o', markersize='6', ls='--') 2091 2092 # ------------------------------------------------------------------------------------------------------------------- # 2093 # 折线图点描述 2094 for a_x1, b_y3 in zip(x_data1, y_data3): 2095 if b_y3 > 0: 2096 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=9, font=font) 2097 2098 # ====================================================================================================================# 2099 2100 # 设置x轴和y轴的标签,指明坐标含义 2101 ax1.set_xlabel('lot ID', fontdict={'size': 16}) 2102 # 左边-y轴为:数量模式 2103 ax1.set_ylabel('模组数量', fontdict={'size': 16}) 2104 # 右边-y轴为:百分比形式 2105 ax2.set_ylabel('百分比', fontdict={'size': 16}) 2106 2107 # 左-y轴为:刻度范围,动态调整 2108 max_value_r1 = int(max(y_data1) * 1.3) 2109 min_value_r1 = int(min(y_data1) * 0.9) 2110 if max_value_r1 < 5: 2111 max_value_r1 = 10 # 直接赋值 2112 min_value_r1 = 0 # 直接赋值 2113 ax1.set_ylim(min_value_r1, max_value_r1) 2114 # 右边-y轴为:最大值为100%,小数点2位 2115 ax2.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=2)) 2116 2117 # 设置x轴和y轴刻度字体 2118 labels2 = ax2.get_xticklabels() + ax2.get_yticklabels() 2119 [label.set_fontname('SimHei') for label in labels2] 2120 2121 # 添加图表题 plt.title('双y轴折线图') 2122 plt.title(title_up, color="red", fontsize=16) 2123 2124 # 设置轴标签颜色 2125 # ax1.tick_params('x', colors='Black') 2126 ax1.tick_params('y', colors='royalblue') 2127 ax2.tick_params('y', colors='tomato') 2128 2129 # 设置轴颜色 2130 ax1.spines['left'].set_color('royalblue') 2131 ax2.spines['left'].set_color('royalblue') 2132 ax1.spines['right'].set_color('tomato') 2133 ax2.spines['right'].set_color('tomato') 2134 2135 # 两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉 2136 ax1.spines['top'].set_visible(False) 2137 ax2.spines['top'].set_visible(False) 2138 2139 # 添加图例函数: plt.legend() 2140 # 添加图例 - 添加方向改为以下代码 2141 ax1.legend(loc='upper left') 2142 ax2.legend(loc='upper right') 2143 # 添加图例 - 将`图例合并改为以下代码 2144 # lines = line1 + line2 + line3 + line4 2145 # lines = line3 + line4 2146 # labels = [h.get_label() for h in lines] 2147 # plt.legend(lines, labels, loc='upper right') 2148 2149 # 设置中文显示 2150 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体) 2151 plt.rcParams['axes.unicode_minus'] = False 2152 2153 # 虚拟背景线 2154 plt.grid(True, linestyle="--") 2155 2156 # 展示图片 2157 # plt.show() 2158 # 显示柱状图时间,单位s 2159 time_v1 = 1 2160 while time_v1 != 0: 2161 print('显示倒计时:%d s' % time_v1) 2162 plt.pause(1) 2163 time_v1 = time_v1 - 1 2164 print('直方图显示完成') 2165 2166 # 图片保存对应文件 2167 picture_m = './4_result_ft/picture/' + bin_name + r".jpg" 2168 plt.savefig(picture_m) 2169 plt.draw() 2170 print('图片保存对应文件-完成') 2171 plt.close() # 关闭图表显示 2172 2173 2174 ''' 2175 # ====================================================================================================================# 2176 # 本月 --- 不良品BIN --- 索引处理分类 2177 # ====================================================================================================================# 2178 ''' 2179 2180 2181 def index_processing_c1(): 2182 print("#**** index_processing_c1 ****#") 2183 2184 2185 ''' 2186 #---------------------------------------------------------------------------------------------------------------# 2187 # vi5300_ft_wc_handle_v1 2188 #---------------------------------------------------------------------------------------------------------------# 2189 ''' 2190 2191 2192 def vi5300_ft_wc_handle_v1(all_data): 2193 # global list_month_v12_n 2194 print('进入函数>>>: vi5300_ft_wc_handle_v1 ...') 2195 datetime_object_s = datetime.datetime.now() 2196 print("datetime_object_s :", datetime_object_s) 2197 2198 # print('全部数据显示: ',pd.DataFrame(all_data)) # 全部数据显示 2199 # print(pd.DataFrame(all_data,columns=[0])) # HANDLER 测试日期 2200 all_raw_data = all_data # raw data 另外保存 2201 data_columns_C0 = pd.DataFrame(all_data, columns=[0]) # 第0列:测试日期 2202 print("summary number:", len(data_columns_C0)) 2203 print("分类存储到不同列表") 2204 2205 datetime_object_1 = datetime.datetime.now() 2206 # print("datetime_object_1 :", datetime_object_1) 2207 for index_a in range(1, len(data_columns_C0)): # 第0列:测试日期需要去除 2208 str_v1_name = str(data_columns_C0.values[index_a]) 2209 2210 # TODO 关闭 年 索引 2211 # str_v1_year = str_v1_name[2:6] 2212 str_v1_month = str_v1_name[7:9] 2213 # TODO 关闭 天 索引 2214 # str_v1_day = str_v1_name[10:12] 2215 2216 # 提取年月日 2217 # print("序号:", index_a, '强制转换: ', str_v1_name) 2218 # print('year: ', str_v1_name[2:6]) 2219 # print('month: ', str_v1_name[7:9]) 2220 # print('day: ', str_v1_name[10:12]) 2221 2222 # TODO 按年-当前省略,后续添加分类 2223 list_month_v12_n = monthly_class_handle_v12(str_v1_month, index_a) 2224 # 2225 # print('显示汇总后每月分类:',list_month_v12_n) 2226 datetime_object_2 = datetime.datetime.now() 2227 print("datetime_object_2 :", datetime_object_2, '耗时:', (datetime_object_2 - datetime_object_1)) 2228 2229 # # # TODO 统计本年度 按月索引数据-汇总数据 2230 # print("统计本年度 按月索引数据-汇总数据") # 起始位=1 2231 # for index_a in range(1, 13): 2232 # print('第%d月数据' % index_a, list_month_v12_n[index_a]) 2233 2234 # 单一月份数据汇总处理 2235 # print("传入1: ", list_month_v12_n) 2236 2237 # ---------------------------------------------------------------------------------------------------------------- # 2238 print("*** 请输入查询VI5300-FT 伟测月份 ***") 2239 month_in = input() 2240 # month_input1 = 11 2241 month_input1 = int(month_in) 2242 print("传入月份长度:", len(list_month_v12_n[month_input1])) 2243 # 根据raw data 数据生成结果图片和异常数据 2244 single_month_summary_v1(list_month_v12_n, all_raw_data) 2245 # 根据结果图片生成 html 报告 2246 generate_report_summary(month_input1) 2247 2248 2249 ''' 2250 #---------------------------------------------------------------------------------------------------------------# 2251 # get_all_files_in_the_folder 备用:获取这个目录下所有文件的名字 2252 #---------------------------------------------------------------------------------------------------------------# 2253 ''' 2254 2255 2256 def get_all_files_in_the_folder(): 2257 # 在对文件进行操作时,某些时候需要获取当前文件夹下所有文件的文件名,如获取这个目录下所有文件的名字 2258 # path定义要获取的文件名称的目录 2259 input_path1 = r'./3_summary_ft' 2260 # os.listdir()方法获取文件夹名字,返回数组 2261 file_name_list = os.listdir(input_path1) 2262 print(file_name_list) 2263 # 转为转为字符串 2264 file_name = str(file_name_list) 2265 # replace替换"["、"]"、" "、"'" 2266 file_name = file_name.replace("[", "").replace("]", "").replace("'", "").replace(",", "\n").replace(" ", "") 2267 # 创建并打开文件list.txt 2268 f = open(input_path1 + "\\" + "文件list.txt", "a") 2269 # 将文件下名称写入到"文件list.txt" 2270 f.write(file_name) 2271 2272 2273 ''' 2274 # =================================================================================================================================================# 2275 # 上方为vi5300-ft-wc 2276 # ---------------------------------------- 分割线--------------------------------------------------------------------------------------------------# 2277 # 下方为vi5300-ft-wc 2278 # =================================================================================================================================================# 2279 ''' 2280 2281 ''' 2282 #---------------------------------------------------------------------------------------------------------------# 2283 # read_excel 2284 #---------------------------------------------------------------------------------------------------------------# 2285 ''' 2286 2287 2288 def read_excel_xx(path_s1): 2289 # current_directory = os.path.dirname(os.path.abspath(__file__)) 2290 # print("获取当前绝对路径:",current_directory) 2291 input_path_s1 = path_s1 2292 # input_path_s1 = r'./3_summary_ft' # path定义要获取的文件名称的目录 2293 file_name_list = os.listdir(input_path_s1) # os.listdir()方法获取文件夹名字,返回数组 2294 print("获取文件夹列表:\n", file_name_list) 2295 2296 # 拼接路径 -- 仅仅获取第一个 2297 input_path_s2 = input_path_s1 + '\\' + file_name_list[0] 2298 2299 # print("pandas 版本: ", pd.__version__) 2300 # 读取一张Sheet 要读取的工作表可以由参数 sheet_name 指定。通过以 0 开头的数字或工作表名称指定。 2301 work_pd1 = pd.read_excel(io=input_path_s2, sheet_name=0, header=None) # 2302 pd.set_option('display.max_columns', None) # 显示完整的行 2303 pd.set_option('display.max_rows', None) # 显示完整的列 2304 pd.set_option('display.expand_frame_repr', False) # 设置不折叠数据 2305 pd.set_option('display.float_format', lambda x: '%.2f' % x) # 设置不以科学计数法显示 2306 # 读取导入Excel所有数据, 2307 # print(work_pd1) 2308 # print(type(work_pd1)) 2309 2310 return work_pd1 2311 2312 2313 ''' 2314 #---------------------------------------------------------------------------------------------------------------# 2315 # vi5300_ft_xx_handle_v2 2316 #---------------------------------------------------------------------------------------------------------------# 2317 ''' 2318 2319 2320 def vi5300_ft_xx_handle_v2(all_data): 2321 print('进入函数>>>: vi5300_ft_xx_handle_v2 ...') 2322 datetime_object_s = datetime.datetime.now() 2323 print("datetime_object_s :", datetime_object_s) 2324 2325 # print('全部数据显示: ',pd.DataFrame(all_data)) # 全部数据显示 2326 # print(pd.DataFrame(all_data,columns=[0])) # HANDLER 测试日期 2327 all_raw_data = all_data # raw data 另外保存 2328 data_columns_C0 = pd.DataFrame(all_data, columns=[0]) # 第0列:测试日期 2329 print("summary number:", len(data_columns_C0)) 2330 print("分类存储到不同列表") 2331 # ------------------------------------------------------------------------------------------------------------------ # 2332 datetime_object_1 = datetime.datetime.now() 2333 # print("datetime_object_1 :", datetime_object_1) 2334 # ------------------------------------------------------------------------------------------------------------------ # 2335 for index_a in range(1, len(data_columns_C0)): # 第0列:测试日期需要去除 2336 str_v1_name = str(data_columns_C0.values[index_a]) 2337 2338 # TODO 关闭 年 索引 2339 # str_v1_year = str_v1_name[2:6] 2340 str_v1_month = str_v1_name[7:9] 2341 # TODO 关闭 天 索引 2342 # str_v1_day = str_v1_name[10:12] 2343 2344 # 提取年月日 2345 # print("序号:", index_a, '强制转换: ', str_v1_name) 2346 # print('year: ', str_v1_name[2:6]) 2347 # print('month: ', str_v1_name[7:9]) 2348 # print('day: ', str_v1_name[10:12]) 2349 2350 # TODO 按年-当前省略,后续添加分类 2351 list_month_m12 = monthly_handle_v12_xx(str_v1_month, index_a) 2352 # 2353 # print('显示汇总后每月分类:',list_month_m12) 2354 # ------------------------------------------------------------------------------------------------------------------ # 2355 datetime_object_2 = datetime.datetime.now() 2356 print("datetime_object_2 :", datetime_object_2, '耗时:', (datetime_object_2 - datetime_object_1)) 2357 # ------------------------------------------------------------------------------------------------------------------ # 2358 2359 # # # TODO 统计本年度 按月索引数据-汇总数据 2360 print("统计本年度 按月索引数据-汇总数据") # 起始位=1 2361 for index_a in range(1, 13): 2362 print('第%d月数据' % index_a, list_month_m12[index_a]) 2363 2364 # 单一月份数据汇总处理 2365 # print("传入1: ", list_month_v12_n) 2366 2367 # ---------------------------------------------------------------------------------------------------------------- # 2368 print("*** 请输入查询讯芯月份 ***") 2369 month_h1 = input() 2370 # month_input1 = 11 2371 month_input1 = int(month_h1) 2372 # 根据raw data 数据生成结果图片和异常数据 2373 print("输入月份长度:", len(list_month_m12[month_input1])) 2374 single_month_v2_xx(month_input1, list_month_m12, all_raw_data) 2375 # 2376 # # 根据结果图片生成 html 报告 2377 generate_report_ft_xx(month_input1) 2378 2379 2380 ''' 2381 # ====================================================================================================================# 2382 # 按月分类 monthly_handle_v12_xx 讯芯 2383 # ====================================================================================================================# 2384 ''' 2385 # 构造二维数组 2386 2387 var_month_v12_xx = [[], [], [], [], [], [], [], [], [], [], [], [], []] 2388 2389 2390 def monthly_handle_v12_xx(input_month, intput_index): 2391 # print('传入参数: 月份%s 行号%s' % (input_month, intput_index)) 2392 month_def = ['0', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'] 2393 for index_v1 in range(1, 13): # 从1开始遍历 2394 # print('遍历每月找到对应月份:',index_v1 , input_month) 2395 if input_month == month_def[index_v1]: 2396 # print("按月分类: %s \t行号:%s" % (month_def[index_v1], intput_index) , '月份类型:',type( month_def[index_v1])) 2397 month_index = int(month_def[index_v1]) 2398 # print('转换后int-月份类型: ', type(month_index), month_index) 2399 # 添加数据到二维数组中 2400 var_month_v12_xx[month_index].append(intput_index) 2401 # print('对应当月的行数汇总:',var_month_v12_xx[month_index]) 2402 2403 break 2404 # print('显示汇总后每月分类:',var_month_v12_xx) 2405 return var_month_v12_xx 2406 2407 2408 ''' 2409 # ====================================================================================================================# 2410 # 本月数据汇总 - single_month_v2_xx 2411 # ====================================================================================================================# 2412 ''' 2413 2414 2415 def single_month_v2_xx(f_d1, f_d2, f_d3): 2416 print('进入函数>>>: single_month_summary_v2_xx ...') # 注意索引值从0开始,索引1==第1月 2417 month_h1 = f_d1 # 获取月份 2418 s_m_m12 = f_d2[month_h1] # 获取本月行号索引值 s_m_m12 = single month m12 2419 raw_data_h1 = f_d3 # 获取整excel表句柄 2420 2421 # ---------------------------------------------------------------------------------------------------------------- # 2422 2423 time_s = datetime.datetime.now() 2424 print("\ntime_1 :", time_s) 2425 # TODO 手动输入实际模版 2426 # 使用无表头,使用数字强制索引 2427 u1_handler = 1 2428 u1_lot = 4 2429 u1_marking = 9 2430 u1_yield = 13 2431 u1_input = 14 2432 u1_bin1 = 15 2433 u1_bin1_p = 16 2434 u1_bin2 = 17 2435 u1_bin2_p = 18 2436 u1_bin3 = 19 2437 u1_bin3_p = 20 2438 u1_bin4 = 21 2439 u1_bin4_p = 22 2440 u1_bin5 = 23 2441 u1_bin5_p = 24 2442 u1_bin6 = 25 2443 u1_bin6_p = 26 2444 u1_bin7 = 27 2445 u1_bin7_p = 28 2446 u1_bin8 = 29 2447 u1_bin8_p = 30 2448 u1_bin9 = 31 2449 u1_bin9_p = 32 2450 u1_bin13 = 33 2451 u1_bin13_p = 34 2452 u1_bin14 = 35 2453 u1_bin14_p = 36 2454 u1_bin_vm = 37 2455 u1_bin_vm_p = 38 2456 u1_bin_loss = 39 2457 u1_bin_loss_p = 40 2458 u1_bin3_os = 41 2459 u1_bin3_os_p = 42 2460 u1_bin4_iih = 43 2461 u1_bin4_iih_p = 44 2462 u1_bin5_cal = 45 # calibration 2463 u1_bin5_cal_p = 46 2464 u1_bin6_vf = 47 # verify 2465 u1_bin6_vf_p = 48 2466 u1_bin6_ck = 49 # Crosstalk 2467 u1_bin6_ck_p = 50 2468 u1_bin7_power = 51 2469 u1_bin7_power_p = 52 2470 u1_bin7_os = 53 2471 u1_bin7_os_p = 54 2472 u1_bin7_lk = 55 2473 u1_bin7_lk_p = 56 # Leakage 2474 2475 # display_all_header_file_names(55, s_m_m12, raw_data_h1) 2476 # display_all_header_file_names(56, s_m_m12, raw_data_h1) 2477 # ---------------------------------------------------------------------------------------------------------------- # 2478 time_s = datetime.datetime.now() 2479 print("\ntime_s :", time_s, ) 2480 # ---------------------------------------------------------------------------------------------------------------- # 2481 # 具体BIN1处理 通用处理 2482 # ---------------------------------------------------------------------------------------------------------------- # 2483 name_bin = "BIN1" 2484 reorder_bin_info_v2_xx(u1_marking, u1_handler, u1_lot, u1_input, u1_bin1, u1_bin1_p, u1_yield, name_bin, month_h1, s_m_m12, raw_data_h1) 2485 chart_total_info_v2_xx(u1_marking, u1_handler, u1_lot, u1_input, u1_bin1, u1_bin1_p, u1_yield, name_bin, month_h1, s_m_m12, raw_data_h1) 2486 2487 # # ---------------------------------------------------------------------------------------------------------------- # 2488 # # 具体不良品处理 特殊处理 2489 # # name_bin = "BIN2" 不存在 2490 name_bin = "BIN3" 2491 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin3, u1_bin3_os, u1_bin3_p, u1_bin3_os_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2492 # 2493 name_bin = "BIN4" 2494 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin4, u1_bin4_iih, u1_bin4_p, u1_bin4_iih_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2495 # 2496 name_bin = "BIN5" 2497 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin5, u1_bin5_cal, u1_bin5_p, u1_bin5_cal_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2498 # 2499 name_bin = "BIN6_1" 2500 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin6, u1_bin6_vf, u1_bin6_p, u1_bin6_vf_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2501 name_bin = "BIN6_2" 2502 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin6, u1_bin6_ck, u1_bin6_p, u1_bin6_ck_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2503 # 2504 name_bin = "BIN7_1" 2505 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin7, u1_bin7_power, u1_bin7_p, u1_bin7_power_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2506 name_bin = "BIN7_2" 2507 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin7, u1_bin7_os, u1_bin7_p, u1_bin7_os_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2508 name_bin = "BIN7_3" 2509 defective_h2_xx(u1_marking, u1_handler, u1_lot, u1_bin7, u1_bin7_lk, u1_bin7_p, u1_bin7_lk_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2510 # # 备份 2511 # //name_bin = "BIN_loss" 2512 # //defective_handle_v2_se(u1_marking, u1_handler, u1_lot, u1_bin_loss, u1_bin_loss_p, name_bin, month_h1, s_m_m12, raw_data_h1) 2513 2514 # ---------------------------------------------------------------------------------------------------------------- # 2515 time_e = datetime.datetime.now() 2516 print("\ntime_s :", time_e, "耗时:", (time_e - time_s)) 2517 2518 2519 ''' 2520 # ====================================================================================================================# 2521 # 本月-良品BIN1-测试数据汇总分布- reorder_bin_info_v2_xx 2522 # ====================================================================================================================# 2523 ''' 2524 2525 2526 def reorder_bin_info_v2_xx(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 2527 # ---------------------------------------------------------------------------------------------------------------- # 2528 print("#**** reorder_bin_info_v2_xx ****#") 2529 # 开始计时 2530 datetime_object_11 = datetime.datetime.now() 2531 print("datetime_object_11 :", datetime_object_11) 2532 2533 # 使用无表头,使用数字强制索引 -- 第一份引用 2534 xx_handler_n2 = x_p2 2535 xx_lot_n3 = x_p3 2536 xx_month_n2 = z_p2 2537 xx_single_month_d2 = z_p3 2538 xx_raw_data_a2 = z_p4 2539 2540 # 使用无表头,使用数字强制索引 -- 第2份引用 2541 u2_marking = x_p1 2542 u2_handler = x_p2 2543 u2_lot = x_p3 2544 u2_input = y_p1 2545 u2_bin1 = y_p2 2546 u2_bin1_p = y_p3 2547 u2_yield = y_p4 2548 u2_name = z_p1 2549 u2_month = z_p2 2550 # u2_index_m12 = z_p3 2551 u2_raw_data = z_p4 2552 2553 # ---------------------------------------------------------------------------------------------------------------------- # 2554 # 处理1 数据归类 2555 print('绘图处理: 月份< %d >' % xx_month_n2, z_p1) 2556 # 指定月份 - 归类前文件 2557 c_g_name1, c_g_data1 = get_data_bin_v2(xx_lot_n3, xx_single_month_d2, xx_raw_data_a2) 2558 c_g_name2, c_g_data2 = get_data_bin_v2(xx_handler_n2, xx_single_month_d2, xx_raw_data_a2) 2559 print("源1:", c_g_name1, c_g_data1) 2560 print("源2:", c_g_name2, c_g_data2) 2561 2562 # ---------------------------------------------------------------------------------------------------------------- # 2563 lot_list_v1 = [] 2564 lot_list_v3 = [] 2565 for index_a in range(len(c_g_data1)): # len(c_g_data1) 2566 num_v1_lot = xx_single_month_d2[index_a] # 获取本月行号 索引值 2567 str_v1_lot = c_g_data1[index_a][0:6] # 正则表达获取lot ,去除wafer 2568 lot_handler_t1 = c_g_data2[index_a] # 获取附属信息 handler 2569 lot_list_v2 = [num_v1_lot, str_v1_lot, lot_handler_t1] # 3个关键字存储到一维列表中 2570 lot_list_v1.append(lot_list_v2) # 存储到一维列表到二维列表中 2571 lot_list_v3.append(str_v1_lot) # 1个关键字存储到一维列表中 2572 # all raw data 有效映射 2573 print('all data -- 切片lot : ', len(lot_list_v1), lot_list_v1) 2574 2575 # 获取同一列表中相同元素,只保留一种类型 2576 one_lot = [] 2577 for v2_lot in lot_list_v3: 2578 if v2_lot not in one_lot: 2579 one_lot.append(v2_lot) 2580 print('lot中唯一代表名称: ', one_lot) 2581 2582 # 先按照 lot 分类 再按照 handler分类 最后索引-行号 2583 lot_handler_m1 = [] # 重新分类聚合的列表 2584 lot_h1_m1 = [] 2585 lot_h1_m2 = [] 2586 # 先按照 lot 大类分组 2587 for row_v1_w1 in one_lot: 2588 print('每种类型的lot: ', row_v1_w1) 2589 line_re_lot5 = [] 2590 2591 for row_v1 in lot_list_v1: 2592 # print('切片lot中第1个元素-二维列中每行第1个元素: ',row_v1[1]) 2593 if row_v1_w1 == row_v1[1]: 2594 # print('打印相同的元素名称: ',row_v1_w1,row_v1[0],row_v1[1]) 2595 line_re_lot4 = [row_v1[0], row_v1[1], row_v1[2]] # 按照每个lot大类重新组合索引值 2596 line_re_lot5.append(line_re_lot4) 2597 lot_h1_m1.append(row_v1[0]) 2598 lot_h1_m2.append(line_re_lot4) 2599 print('每个lot大类-组合: ', len(line_re_lot5), line_re_lot5) 2600 # -------------------------------------------------------------------------------- # 2601 # # TODO 2602 list_handler_sy1 = line_re_lot5 2603 index_handler_pp = [] 2604 for grapefruit in range(len(list_handler_sy1)): 2605 index_handler = list_handler_sy1[grapefruit] # 获取本月行号 索引值 2606 # print("每列的元素:", index_handler) # 索引+lot+handler 2607 index_m1 = index_handler[2] # 获取 handler 2608 index_handler_pp.append(index_m1) 2609 # all raw data 有效映射 2610 print('all raw data 有效映射: \n', len(index_handler_pp),index_handler_pp) 2611 # 获取同一列表中相同元素,只保留一种类型 2612 one_handler_grape = [] 2613 for grape in index_handler_pp: 2614 if grape not in one_handler_grape: 2615 one_handler_grape.append(grape) 2616 print('handler 唯一代表 名称: ', one_handler_grape) 2617 2618 handler_all = [] 2619 for one_c1 in range(len(one_handler_grape)): 2620 papaya = [] 2621 papaya_mt = [] 2622 for kiwifruit in range(len(list_handler_sy1)): 2623 # print("Index:", one_c1, "Value:", one_handler_grape[one_c1], list_handler_sy1[kiwifruit][2]) 2624 if one_handler_grape[one_c1] == list_handler_sy1[kiwifruit][2]: 2625 # print('匹配:',one_c1 ,one_handler_grape[one_c1], list_handler_sy1[kiwifruit][2]) 2626 papaya.append(list_handler_sy1[kiwifruit]) 2627 # print("打印每行lot的数据:",papaya) 2628 # 同种handler 合并到一个列表-方案1 2629 # handler_all.append(papaya) 2630 # # 同种handler 放置同一级-方案2 2631 for df_one in range(len(papaya)): 2632 handler_all.append(papaya[df_one]) 2633 # print("同一个lot 所有行lot的数据:", len(handler_all), handler_all) 2634 lot_handler_m1 = lot_handler_m1 + handler_all 2635 # 打印重新组合 2636 print("显示重新新组合: \n", len(lot_handler_m1), lot_handler_m1) 2637 # print("是否继续循环") 2638 # input() 2639 # ---------------------------------------------------------------------------------------------------------------- # 2640 2641 lot_handler_index = [] 2642 for index_lh in range(len(lot_handler_m1)): 2643 lot_handler_index.append(lot_handler_m1[index_lh][0]) 2644 # print("lot_handler_index: ", lot_handler_index) 2645 # 替换前 2646 # for index_a in range(1, 13): 2647 # print('第%d月数据' % (index_a), var_month_v12_xx[index_a]) 2648 var_month_v12_xx[xx_month_n2] = lot_handler_index 2649 # 替换后 2650 # for index_a in range(1, 13): 2651 # print('第%d月数据' % (index_a), var_month_v12_xx[index_a]) 2652 index_s_m2 = lot_handler_index 2653 2654 2655 datetime_object_12 = datetime.datetime.now() 2656 print("datetime_object_12 :", datetime_object_12, ' 耗时:', (datetime_object_12 - datetime_object_11)) 2657 # ---------------------------------------------------------------------------------------------------------------------- # 2658 # 绘图 是由上述函数传递的:index_s_m2 2659 histogram_handle_v2_xx(u2_marking, u2_handler, u2_lot, u2_input, u2_bin1, u2_bin1_p, u2_yield, u2_name, u2_month, index_s_m2, u2_raw_data) 2660 2661 datetime_object_13 = datetime.datetime.now() 2662 print("datetime_object_12 :", datetime_object_13, ' 耗时:', (datetime_object_13 - datetime_object_11)) 2663 2664 2665 ''' 2666 # ====================================================================================================================# 2667 # 本月-良品BIN1-测试数据汇总分布-绘图v2-xx histogram_handle_v2_xx 2668 # ====================================================================================================================# 2669 ''' 2670 2671 2672 def histogram_handle_v2_xx(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 2673 print('#---- histogram_handle_v2_xx ----#') 2674 x_axle_n1 = x_p1 2675 x_axle_n2 = x_p2 2676 x_axle_n3 = x_p3 2677 y_total_t1 = y_p1 2678 y_total_t2 = y_p2 2679 y_yield_t1 = y_p3 2680 y_yield_t2 = y_p4 2681 bin_name = z_p1 2682 month_n1 = z_p2 2683 single_month_d1 = z_p3 2684 raw_data_a1 = z_p4 2685 print('绘图处理: 月份< %d >' % month_n1, ) 2686 # 获取每月函数 有效数据 x_axle_n2 2687 x_name1, x_data1 = get_data_bin_v2(x_axle_n1, single_month_d1, raw_data_a1) 2688 x_name2, x_data2 = get_data_bin_v2(x_axle_n2, single_month_d1, raw_data_a1) 2689 x_name3, x_data3 = get_data_bin_v2(x_axle_n3, single_month_d1, raw_data_a1) 2690 y_name1, y_data1 = get_data_bin_v2(y_total_t1, single_month_d1, raw_data_a1) 2691 y_name2, y_data2 = get_data_bin_v2(y_total_t2, single_month_d1, raw_data_a1) 2692 y_name3, y_data3 = get_data_bin_v2(y_yield_t1, single_month_d1, raw_data_a1) 2693 y_name4, y_data4 = get_data_bin_v2(y_yield_t2, single_month_d1, raw_data_a1) 2694 # print(x_name1, x_data1) 2695 # print(x_name2, x_data2) 2696 # print(y_name1, y_data1) 2697 # print(y_name2, y_data2) 2698 # print(y_name3, y_data3) 2699 2700 # ======================================================================================== # 2701 2702 # 整体参数配置 2703 font = FontProperties(size=10) 2704 plt.rcParams["font.sans-serif"] = ['SimHei'] 2705 plt.rcParams['axes.unicode_minus'] = False 2706 plt.rcParams['font.family'] = ['SimHei'] 2707 plt.rcParams['font.sans-serif'] = ['SimHei'] 2708 plt.rcParams['figure.figsize'] = (30, 10) 2709 plt.rc('font', family='SimHei', size=8) 2710 2711 # 创建一个图形和两个y轴 2712 fig, ax1 = plt.subplots(1, 1) # 绘制双Y轴 表示一次性在figure上创建成1*1的网格 2713 2714 # 柱状图柱子宽度 2715 bar_width = 0.4 2716 x_ticks = range(len(x_data1)) # x轴刻度位置 | 折线图x位置 2717 bar_1_x = [(ii - bar_width + 0.2) for ii in x_ticks] # 柱状图1 - x位置 2718 bar_2_x = [(ww - bar_width + 0.6) for ww in x_ticks] 2719 2720 # 设置x轴刻度字体以及方向-单刻度标签 2721 labels1 = ax1.get_xticklabels() + ax1.get_yticklabels() 2722 [label.set_fontname('SimHei') for label in labels1] 2723 # plt.xticks(x_ticks, list(x_data1), rotation=90, ) #x轴刻度位置 | 刻度标签 | 旋转90度 2724 2725 # 设置x轴刻度字体以及方向- 叠加双刻度标签 2726 labels = [] 2727 for two_m1 in range(len(x_data1)): 2728 cell_m2 = x_data3[two_m1][0:6] + ' ' + x_data2[two_m1] + ' ' + x_data1[two_m1] 2729 labels.append(cell_m2) 2730 # labels = x_ticks # 默认 2731 # print('2个叠加后的刻度标签: ',labels) # 2个叠加后的刻度标签 2732 plt.xticks(x_ticks, labels, rotation=90, ) # x轴刻度位置 | 刻度标签 | 旋转90度 2733 # 自适应调整布局+ 指定 解决X轴范围问题 2734 fig.autofmt_xdate(rotation=90) 2735 2736 # -------------------------------------------------------------------------------------- # 2737 # # 同一刻度标签标记为不同颜色 插孔法 升级-适用较为复杂的场景 2738 print(x_name1) 2739 print(x_name2) 2740 print(x_name3) 2741 2742 index_lot_v5 = [] 2743 for index_a in range(len(single_month_d1)): 2744 index_lot = single_month_d1[index_a] # 获取本月行号 索引值 2745 index_m1 = x_data3[index_a][0:6] # 获取本月行号 索引值 2746 index_lot_v5.append(index_m1) 2747 # all raw data 有效映射 2748 print("all raw data 有效映射:", index_lot_v5) 2749 # 获取同一列表中相同元素,只保留一种类型 2750 one_lot_v1 = [] 2751 for v2_lot in index_lot_v5: 2752 if v2_lot not in one_lot_v1: 2753 one_lot_v1.append(v2_lot) 2754 print('lot中唯一代表名称: ', one_lot_v1) 2755 xtick_labels = ax1.get_xticklabels() 2756 colors = ['red', 'green', 'blue', 'purple', 'orange', 'brown', 'gray', 'pink', 'cyan', 'magenta', 'yellow', 'black', ] 2757 # 利用唯一lot去适配列表lot,影射到对应刻度,根据余数去自动识别颜色,默认10种 2758 for x_color in range(len(x_data3)): 2759 # print("x_color: ",x_color,x_data3[x_color][0:6]) 2760 for one_c1 in range(len(one_lot_v1)): 2761 # print("Index:", one_c1, "Value:", one_lot_v1[one_c1]) 2762 if one_lot_v1[one_c1] == x_data3[x_color][0:6]: 2763 one_color_v1 = one_c1 % 10 2764 if one_color_v1 == 0: 2765 xtick_labels[x_color].set_color(colors[0]) 2766 elif one_color_v1 == 1: 2767 xtick_labels[x_color].set_color(colors[1]) 2768 elif one_color_v1 == 2: 2769 xtick_labels[x_color].set_color(colors[2]) 2770 elif one_color_v1 == 3: 2771 xtick_labels[x_color].set_color(colors[3]) 2772 elif one_color_v1 == 4: 2773 xtick_labels[x_color].set_color(colors[4]) 2774 elif one_color_v1 == 5: 2775 xtick_labels[x_color].set_color(colors[5]) 2776 elif one_color_v1 == 6: 2777 xtick_labels[x_color].set_color(colors[6]) 2778 elif one_color_v1 == 7: 2779 xtick_labels[x_color].set_color(colors[7]) 2780 elif one_color_v1 == 8: 2781 xtick_labels[x_color].set_color(colors[8]) 2782 elif one_color_v1 == 9: 2783 xtick_labels[x_color].set_color(colors[9]) 2784 # -------------------------------------------------------------------------------------- # 2785 2786 # 绘制双Y轴 让2个X轴一样,同时创建副坐标轴 2787 ax2 = ax1.twinx() 2788 2789 # 图例文件描述-动态变化 2790 title_up = "本月测试 " + bin_name + " 分布" 2791 legend_x3 = y_name1 2792 legend_x4 = y_name2 2793 legend_y3 = y_name3 2794 legend_y4 = y_name4 2795 2796 # ====================================================================================================================# 2797 # 绘制柱状图 2798 # bar1 = ax1.bar(bar_1_x, y_data1, label='y1轴', color='lightblue', width=0.4) 2799 # bar2 = ax1.bar(bar_2_x, y_data2, label='y2轴', color='gold', width=0.4) 2800 bar3 = ax1.bar(bar_1_x, y_data1, label=legend_x3, color='lightblue', width=bar_width, linewidth=0.2, edgecolor="white") 2801 bar4 = ax1.bar(bar_2_x, y_data2, label=legend_x4, color='gold', width=bar_width, linewidth=0.2, edgecolor="white") 2802 2803 # 绘制折线图 2804 # line1 = ax1.plot(x_data1, y_data1, label='y1轴', color='royalblue', marker='o', ls='-.') 2805 # line2 = ax2.plot(x_data1, y_data2, label='y2轴', color='tomato', marker='o', ls='--') 2806 line3 = ax2.plot(x_data1, y_data3, label=legend_y3, color='Lightgreen', marker='o', markersize='6', ls='--') 2807 line4 = ax2.plot(x_data1, y_data4, label=legend_y4, color='red', marker='.', markersize='6', ls='-') 2808 2809 # 折线图点描述 2810 for a_x1, b_y3, c_y4 in zip(x_data1, y_data3, y_data4): 2811 if b_y3 < c_y4: 2812 print("# 低于卡控线: ", a_x1, file=run_log) 2813 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=12, font=font) 2814 else: 2815 # print("# 正常模组: ", a_x1) 2816 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=8, font=font) 2817 ax2.text(1, c_y4, '{:.2f}%'.format(c_y4 * 100), ha='center', va='bottom', fontsize=11, font=font) # 只显示一个 2818 2819 # ====================================================================================================================# 2820 2821 # 设置x轴和y轴的标签,指明坐标含义 2822 ax1.set_xlabel('lot ID', fontdict={'size': 16}) 2823 # 左边-y轴为:数量模式 2824 ax1.set_ylabel('模组数量', fontdict={'size': 16}) 2825 # 右边-y轴为:百分比形式 2826 ax2.set_ylabel('百分比', fontdict={'size': 16}) 2827 2828 # 左-y轴为:刻度范围,动态调整 2829 max_value_r1 = int(max(y_data1) * 1.3) 2830 min_value_r1 = int(min(y_data1) * 0.9) 2831 if max_value_r1 < 5: 2832 max_value_r1 = 10 # 直接赋值 2833 min_value_r1 = 0 # 直接赋值 2834 ax1.set_ylim(min_value_r1, max_value_r1) 2835 # 右边-y轴为:最大值为100%,小数点2位 2836 ax2.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=2)) 2837 2838 # 设置x轴和y轴刻度字体 2839 labels2 = ax2.get_xticklabels() + ax2.get_yticklabels() 2840 [label.set_fontname('SimHei') for label in labels2] 2841 2842 # 添加图表题 plt.title('双y轴折线图') 2843 plt.title(title_up, color="red", fontsize=16) 2844 2845 # 设置轴标签颜色 2846 # ax1.tick_params('x', colors='Black') 2847 ax1.tick_params('y', colors='royalblue') 2848 ax2.tick_params('y', colors='tomato') 2849 2850 # 设置轴颜色 2851 ax1.spines['left'].set_color('royalblue') 2852 ax2.spines['left'].set_color('royalblue') 2853 ax1.spines['right'].set_color('tomato') 2854 ax2.spines['right'].set_color('tomato') 2855 2856 # 两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉 2857 ax1.spines['top'].set_visible(False) 2858 ax2.spines['top'].set_visible(False) 2859 2860 # 添加图例函数: plt.legend() 2861 # 添加图例 - 添加方向改为以下代码 2862 ax1.legend(loc='upper left') 2863 ax2.legend(loc='upper right') 2864 # 添加图例 - 将`图例合并改为以下代码 2865 # lines = line1 + line2 + line3 + line4 2866 # lines = line3 + line4 2867 # labels = [h.get_label() for h in lines] 2868 # plt.legend(lines, labels, loc='upper right') 2869 2870 # 设置中文显示 2871 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体) 2872 plt.rcParams['axes.unicode_minus'] = False 2873 2874 # 虚拟背景线 2875 plt.grid(True, linestyle="--") 2876 2877 # 展示图片 2878 # plt.show() 2879 # 显示柱状图时间,单位s 2880 time_v1 = 1 2881 while time_v1 != 0: 2882 print('显示倒计时:%d s' % time_v1) 2883 plt.pause(1) 2884 time_v1 = time_v1 - 1 2885 print('直方图显示完成') 2886 2887 # 图片保存对应文件 2888 picture_m = './6_result_ft_xx/picture/' + bin_name + r".jpg" 2889 plt.savefig(picture_m) 2890 plt.draw() 2891 print('图片保存对应文件-完成') 2892 plt.close() # 关闭图表显示 2893 2894 2895 ''' 2896 # ====================================================================================================================# 2897 # 本月-良品BIN1-handler&lot汇总分布-通用2模板数据处理 2898 # ====================================================================================================================# 2899 ''' 2900 2901 2902 def chart_total_info_v2_xx(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 2903 print('>>> chart_total_info_v2_xx ...') 2904 # u1_marking, u1_handler, u1_lot, u1_input, u1_bin1, u1_bin1_p, u1_yield, name_bin, month_h1, index_s_m0, raw_data_h1 2905 # 开始计时 2906 datetime_object_21 = datetime.datetime.now() 2907 print("datetime_object_21 :", datetime_object_21) 2908 # 1按照总数汇总 2909 # 按照handler类型汇总-4种 2910 # 按照lot类型汇总-动态 2911 x_axle_e1 = x_p1 2912 x_axle_e2 = x_p2 2913 x_axle_e3 = x_p3 2914 y_total_k1 = y_p1 2915 y_total_k2 = y_p2 2916 y_yield_k3 = y_p3 2917 y_yield_k4 = y_p4 2918 bin_name = z_p1 2919 month_u1 = z_p2 2920 single_month_g1 = z_p3 2921 raw_data_t1 = z_p4 2922 print('汇总处理: 月份< %d >' % month_u1, ) 2923 print(single_month_g1) 2924 x_name_f1, x_data_j1 = get_data_bin_v2(x_axle_e1, single_month_g1, raw_data_t1) 2925 x_name_f2, x_data_j2 = get_data_bin_v2(x_axle_e2, single_month_g1, raw_data_t1) 2926 x_name_f3, x_data_j3 = get_data_bin_v2(x_axle_e3, single_month_g1, raw_data_t1) 2927 y_name_f1, y_data_j1 = get_data_bin_v2(y_total_k1, single_month_g1, raw_data_t1) 2928 y_name_f2, y_data_j2 = get_data_bin_v2(y_total_k2, single_month_g1, raw_data_t1) 2929 y_name_f3, y_data_j3 = get_data_bin_v2(y_yield_k3, single_month_g1, raw_data_t1) 2930 y_name_f4, y_data_j4 = get_data_bin_v2(y_yield_k4, single_month_g1, raw_data_t1) 2931 # print('源1:', x_name_f1, x_data_j1) # MARKING 2932 # print('源2:', x_name_f2, x_data_j2) # HANDLER 2933 # print('源3:', x_name_f3, x_data_j3) # LOTID 2934 print('源4:', y_name_f1, y_data_j1) # Input 2935 print('源5:', y_name_f2, y_data_j2) # BIN01(Good) 2936 # print('源6:', y_name_f3, y_data_j3) # BIN01(%) 2937 # print('源7:', y_name_f4, y_data_j4) # YIELDLIMIT 2938 2939 # def limit 2940 handler_syl = 0.9000 2941 lot_syl = 0.9000 2942 2943 # 创建一个新的 Excel 文件 2944 workbook = openpyxl.Workbook() 2945 one_sheet = workbook.active 2946 test_result_v0 = ["project_name", "结果", "实际良率", "目标良率", "投入数量(ea)", "实际产出(ea)"] 2947 one_sheet.append(test_result_v0) # 追加一行数据 2948 # 动态保存路径 2949 # target_name = str(month_u1) + "月_汇总统计结果.xlsx" 2950 target_name = "月度_汇总统计结果.xlsx" 2951 target_path = r'./6_result_ft_xx/picture/' + target_name 2952 # 保存数据 2953 # workbook.save(target_path) 2954 2955 # ---------------------------------------------------------------------------------------------------------------- # 2956 # 1按照总数汇总 2957 r1_input = np.sum(y_data_j1) 2958 r1_bin1 = np.sum(y_data_j2) 2959 r1_yield = r1_bin1 / r1_input 2960 r1_yield_percent = "{:.2%}".format(r1_yield) 2961 r1_limit = "{:.2%}".format(y_data_j4[0]) 2962 r1_state = 'pass' if r1_yield > y_data_j4[0] else 'fail' 2963 print( 2964 'summary 结果:%s 实际良率:%s 目标良率:%s 投入数量(ea): %d 实际产出(ea):%d \n' % (r1_state, r1_yield_percent, r1_limit, r1_input, r1_bin1)) 2965 2966 test_result_v0 = ["summary", r1_state, r1_yield_percent, r1_limit, r1_input, r1_bin1] 2967 one_sheet.append(test_result_v0) # 追加一行数据 2968 # ---------------------------------------------------------------------------------------------------------------- # 2969 datetime_21_1 = datetime.datetime.now() 2970 print("datetime_21_1 :", datetime_21_1, ' 耗时:', (datetime_21_1 - datetime_object_21)) 2971 # ---------------------------------------------------------------------------------------------------------------- # 2972 # # 按照handler类型汇总-4种 2973 # # 仅按照handler分类 顺序重新归类 2974 2975 index_handler_pp = [] 2976 for grapefruit in range(len(single_month_g1)): 2977 index_handler = single_month_g1[grapefruit] # 获取本月行号 索引值 2978 index_m1 = x_data_j2[grapefruit][0:6] # 获取本月行号 索引值 2979 index_handler_pp.append(index_m1) 2980 # all raw data 有效映射 2981 # print('all raw data 有效映射: \n',index_lot_hv5) 2982 # 获取同一列表中相同元素,只保留一种类型 2983 one_handler_grape = [] 2984 for grape in index_handler_pp: 2985 if grape not in one_handler_grape: 2986 one_handler_grape.append(grape) 2987 print('handler 唯一代表 名称: ', one_handler_grape) 2988 2989 handler_all = [] 2990 for one_c1 in range(len(one_handler_grape)): 2991 papaya = [] 2992 for kiwifruit in range(len(x_data_j2)): 2993 # print("Index:", one_c1, "Value:", one_lot_orange[one_c1], x_data_j3[watermelon][0:6]) 2994 if one_handler_grape[one_c1] == x_data_j2[kiwifruit]: 2995 # print('匹配:',one_c1 ,one_lot_orange[one_c1], x_data_j3[watermelon][0:6]) 2996 handler_element = [single_month_g1[kiwifruit], x_data_j2[kiwifruit], y_data_j1[kiwifruit], y_data_j2[kiwifruit]] 2997 papaya.append(handler_element) 2998 # print("打印每行lot的数据:",papaya) 2999 handler_all.append(papaya) 3000 # 3001 print("打印每行lot的数据:", handler_all) 3002 3003 # # 3004 strawberry_a1 = [] 3005 strawberry_b1 = [] 3006 strawberry_b2 = [] 3007 strawberry_b3 = [] 3008 strawberry_b4 = [] 3009 # 根据lot列表-自动循环方案 3010 for strawberry in range(len(handler_all)): 3011 line_cache21 = [] 3012 line_cache22 = [] 3013 # print("目的获取handler的个数 -第%d个 "%banana) 3014 for sub_index1 in range(len(handler_all[strawberry])): 3015 # print("目的获取三维数组的每行的列表值(一维):",handler_all[strawberry][sub_index1]) 3016 for sub_index2 in range(len(one_handler_grape)): 3017 # print('打印比对的数值:',one_handler_grape[sub_index2], handler_all[strawberry][sub_index1][1]) 3018 if one_handler_grape[sub_index2] == handler_all[strawberry][sub_index1][1]: 3019 line_cache21.append(handler_all[strawberry][sub_index1][2]) 3020 line_cache22.append(handler_all[strawberry][sub_index1][3]) 3021 h1_input = np.sum(line_cache21) 3022 h1_output = np.sum(line_cache22) 3023 h1_yield = h1_output / h1_input 3024 h1_yield_percent = "{:.2%}".format(h1_yield) 3025 h1_state = 'pass' if h1_yield > lot_syl else 'fail' 3026 print('handler -%s >>> \t结果%s \t良率: %s \t投入数量: %d \t实际产出: %d ' % ( 3027 handler_all[strawberry][0][1][0:6], h1_state, h1_yield_percent, h1_input, h1_output)) 3028 project_n1 = 'handler-' + handler_all[strawberry][sub_index1][1][0:6] 3029 h1_syl = "{:.2%}".format(lot_syl) 3030 test_result_v0 = [project_n1, h1_state, h1_yield_percent, h1_syl, h1_input, h1_output] 3031 one_sheet.append(test_result_v0) # 追加一行数据 3032 # 存储列表-绘图 3033 strawberry_a1.append(one_handler_grape[strawberry]) 3034 strawberry_b1.append(h1_input) 3035 strawberry_b2.append(h1_output) 3036 strawberry_b3.append(h1_yield) 3037 strawberry_b4.append(handler_syl) 3038 # 绘图 3039 t_category = "handler" 3040 histogram_handle_v2_xx_se(strawberry_a1, strawberry_b1, strawberry_b2, strawberry_b3, strawberry_b4, t_category) 3041 3042 # print('Handler PP-%d >>> \t结果:%s \t实际: %s \t投入数量: %d \t实际产出: %d ' % (banana, h1_state, h1_yield_percent, h1_input, h1_output,)) 3043 # project_n1 = 'Handler PP-' + str(banana) 3044 # h1_syl = h1_yield_percent = "{:.2%}".format(handler_syl) 3045 # test_result_v0 = [project_n1, h1_state, h1_yield, h1_syl, h1_input, h1_output] 3046 # one_sheet.append(test_result_v0) # 追加一行数据 3047 # 3048 # # 存储列表-绘图 3049 # banana_a1.append(handler_name[index_n1]) 3050 # banana_b1.append(h1_input) 3051 # banana_b2.append(h1_output) 3052 # banana_b3.append(h1_yield) 3053 3054 # ---------------------------------------------------------------------------------------------------------------- # 3055 datetime_21_2 = datetime.datetime.now() 3056 print("datetime_21_2 :", datetime_21_2, ' 耗时:', (datetime_21_2 - datetime_21_1)) 3057 print("\n") 3058 # ---------------------------------------------------------------------------------------------------------------- # 3059 # 按照lot类型汇总-动态 3060 index_lot_lv5 = [] 3061 for orange in range(len(single_month_g1)): 3062 index_lot = single_month_g1[orange] # 获取本月行号 索引值 3063 index_m1 = x_data_j3[orange][0:6] # 获取本月行号 索引值 3064 index_lot_lv5.append(index_m1) 3065 # all raw data 有效映射 3066 # print('all raw data 有效映射: \n',index_lot_lv5) 3067 # 获取同一列表中相同元素,只保留一种类型 3068 one_lot_orange = [] 3069 for orange_lot in index_lot_lv5: 3070 if orange_lot not in one_lot_orange: 3071 one_lot_orange.append(orange_lot) 3072 print('lot 唯一代表 名称: ', one_lot_orange) 3073 3074 km_lot_all = [] 3075 for one_c1 in range(len(one_lot_orange)): 3076 km_lot = [] 3077 for watermelon in range(len(x_data_j3)): 3078 # print("Index:", one_c1, "Value:", one_lot_orange[one_c1], x_data_j3[watermelon][0:6]) 3079 if one_lot_orange[one_c1] == x_data_j3[watermelon][0:6]: 3080 # print('匹配:',one_c1 ,one_lot_orange[one_c1], x_data_j3[watermelon][0:6]) 3081 km_lot_element = [single_month_g1[watermelon], x_data_j3[watermelon], y_data_j1[watermelon], y_data_j2[watermelon]] 3082 km_lot.append(km_lot_element) 3083 # print("打印每行lot的数据:",km_lot) 3084 km_lot_all.append(km_lot) 3085 # print("打印每行lot的数据:",km_lot_all) 3086 3087 # 3088 banana_a1 = [] 3089 banana_b1 = [] 3090 banana_b2 = [] 3091 banana_b3 = [] 3092 banana_b4 = [] 3093 # 根据lot列表-自动循环方案 3094 for banana in range(len(km_lot_all)): 3095 line_cache21 = [] 3096 line_cache22 = [] 3097 # print("目的获取handler的个数 -第%d个 "%banana) 3098 for sub_index1 in range(len(km_lot_all[banana])): 3099 # print("目的获取三维数组的每行的列表值(一维):",km_lot_all[banana][sub_index1]) 3100 for sub_index2 in range(len(one_lot_orange)): 3101 # print('打印比对的数值:',one_lot_orange[sub_index2], km_lot_all[banana][sub_index1][1][0:6]) 3102 if one_lot_orange[sub_index2] == km_lot_all[banana][sub_index1][1][0:6]: 3103 line_cache21.append(km_lot_all[banana][sub_index1][2]) 3104 line_cache22.append(km_lot_all[banana][sub_index1][3]) 3105 l1_input = np.sum(line_cache21) 3106 l1_output = np.sum(line_cache22) 3107 l1_yield = l1_output / l1_input 3108 l1_yield_percent = "{:.2%}".format(l1_yield) 3109 l1_state = 'pass' if l1_yield > lot_syl else 'fail' 3110 print('lot-%s >>> \t结果%s \t良率: %s \t投入数量: %d \t实际产出: %d ' % ( 3111 km_lot_all[banana][0][1][0:6], l1_state, l1_yield_percent, l1_input, l1_output)) 3112 project_n1 = 'lot-' + km_lot_all[banana][sub_index1][1][0:6] 3113 l1_syl = "{:.2%}".format(lot_syl) 3114 test_result_v0 = [project_n1, l1_state, l1_yield_percent, l1_syl, l1_input, l1_output] 3115 one_sheet.append(test_result_v0) # 追加一行数据 3116 3117 # 存储列表-绘图 3118 banana_a1.append(one_lot_orange[banana]) 3119 banana_b1.append(l1_input) 3120 banana_b2.append(l1_output) 3121 banana_b3.append(l1_yield) 3122 banana_b4.append(lot_syl) 3123 # 绘图 3124 t_category = "lot" 3125 histogram_handle_v2_xx_se(banana_a1, banana_b1, banana_b2, banana_b3, banana_b4, t_category) 3126 # ---------------------------------------------------------------------------------------------------------------- # 3127 datetime_21_3 = datetime.datetime.now() 3128 print("datetime_21_3 :", datetime_21_3, ' 耗时:', (datetime_21_3 - datetime_21_2)) 3129 # ---------------------------------------------------------------------------------------------------------------- # 3130 # 保存数据 3131 workbook.save(target_path) 3132 3133 datetime_object_22 = datetime.datetime.now() 3134 print("\n运行结束 :", datetime_object_22, ' 总耗时:', (datetime_object_22 - datetime_object_21)) 3135 3136 3137 ''' 3138 # ====================================================================================================================# 3139 # 本月-良品BIN1-handler&lot汇总分布-绘图2 3140 # ====================================================================================================================# 3141 ''' 3142 3143 3144 def histogram_handle_v2_xx_se(x_p1, y_p1, y_p2, y_p3, y_p4, z_p1): 3145 print('#---- histogram_handle_v2_xx_se ----#') 3146 x_axle_n1 = x_p1 3147 y_total_t1 = y_p1 3148 y_total_t2 = y_p2 3149 y_yield_t1 = y_p3 3150 y_yield_t2 = y_p4 3151 z_name_km1 = z_p1 3152 3153 # ======================================================================================== # 3154 # 整体参数配置 3155 font = FontProperties(size=10) 3156 plt.rcParams["font.sans-serif"] = ['SimHei'] 3157 plt.rcParams['axes.unicode_minus'] = False 3158 plt.rcParams['font.family'] = ['SimHei'] 3159 plt.rcParams['font.sans-serif'] = ['SimHei'] 3160 plt.rcParams['figure.figsize'] = (30, 10) 3161 plt.rc('font', family='SimHei', size=8) 3162 3163 # 创建一个图形和两个y轴 3164 fig, ax1 = plt.subplots(1, 1) # 绘制双Y轴 表示一次性在figure上创建成1*1的网格 3165 3166 # 柱状图柱子宽度 3167 bar_width = 0.2 3168 x_ticks = range(len(x_axle_n1)) # x轴刻度位置 | 折线图x位置 3169 bar_1_x = [(ii - bar_width + 0.1) for ii in x_ticks] # 柱状图1 - x位置 3170 bar_2_x = [(ww - bar_width + 0.3) for ww in x_ticks] 3171 3172 # 设置x轴刻度字体以及方向-单刻度标签 3173 labels1 = ax1.get_xticklabels() + ax1.get_yticklabels() 3174 [label.set_fontname('SimHei') for label in labels1] 3175 # plt.xticks(x_ticks, list(x_data1), rotation=90, ) #x轴刻度位置 | 刻度标签 | 旋转90度 3176 3177 # 设置x轴刻度字体以及方向- 叠加双刻度标签 3178 labels = [] 3179 for two_m1 in range(len(x_axle_n1)): 3180 cell_m2 = x_axle_n1[two_m1] 3181 labels.append(cell_m2) 3182 # labels = x_ticks # 默认 3183 # print('2个叠加后的刻度标签: ',labels) # 2个叠加后的刻度标签 3184 plt.xticks(x_ticks, labels, rotation=90, ) # x轴刻度位置 | 刻度标签 | 旋转90度 3185 # 自适应调整布局+ 指定 解决X轴范围问题 3186 fig.autofmt_xdate(rotation=90) 3187 3188 # -------------------------------------------------------------------------------------- # 3189 # # 同一刻度标签标记为不同颜色 插孔法 3190 # 第1种方案 3191 xtick_labels = ax1.get_xticklabels() 3192 colors = ['red', 'green', 'blue', 'purple', 'orange', 'black', 'brown', 'gray', 'pink', 'yellow', 'cyan', 'magenta'] 3193 for x_colors in range(int(len(x_axle_n1) / 4)): 3194 # print(0+x_colors*4, 1+x_colors*4, 2+x_colors*4,3+x_colors*4) 3195 x_colors_a = 0 + x_colors * 4 3196 x_colors_b = 1 + x_colors * 4 3197 x_colors_c = 2 + x_colors * 4 3198 x_colors_d = 3 + x_colors * 4 3199 xtick_labels[x_colors_a].set_color('red') 3200 xtick_labels[x_colors_b].set_color('blue') 3201 xtick_labels[x_colors_c].set_color('orange') 3202 xtick_labels[x_colors_d].set_color('magenta') 3203 3204 # -------------------------------------------------------------------------------------- # 3205 3206 # 绘制双Y轴 让2个X轴一样,同时创建副坐标轴 3207 ax2 = ax1.twinx() 3208 3209 # 图例文件描述-动态变化 3210 title_up = "本月测试 " + z_name_km1 + " 分布" 3211 legend_x3 = "input" 3212 legend_x4 = "output" 3213 legend_y3 = "yield" 3214 legend_y4 = "limit" 3215 3216 # ====================================================================================================================# 3217 # 绘制柱状图 3218 # bar1 = ax1.bar(bar_1_x, y_data1, label='y1轴', color='lightblue', width=0.4) 3219 # bar2 = ax1.bar(bar_2_x, y_data2, label='y2轴', color='gold', width=0.4) 3220 bar3 = ax1.bar(bar_1_x, y_total_t1, label=legend_x3, color='lightblue', width=bar_width, linewidth=0.2, edgecolor="white") 3221 bar4 = ax1.bar(bar_2_x, y_total_t2, label=legend_x4, color='gold', width=bar_width, linewidth=0.2, edgecolor="white") 3222 # 绘制柱描述 3223 for a, b, c in zip(bar_1_x, y_total_t1, y_total_t2): 3224 ax1.text(a - 0.1, b, '%d' % b, ha='center', va='bottom', fontsize=8, font=font, ) 3225 ax1.text(a + 0.3, c, '%d' % c, ha='center', va='bottom', fontsize=8, font=font, ) 3226 3227 # 3228 # 绘制折线图 3229 # line1 = ax1.plot(x_data1, y_data1, label='y1轴', color='royalblue', marker='o', ls='-.') 3230 # line2 = ax2.plot(x_data1, y_data2, label='y2轴', color='tomato', marker='o', ls='--') 3231 line3 = ax2.plot(x_axle_n1, y_yield_t1, label=legend_y3, color='Lightgreen', marker='o', markersize='6', ls='--') 3232 line4 = ax2.plot(x_axle_n1, y_yield_t2, label=legend_y4, color='red', marker='.', markersize='6', ls='-') 3233 3234 # 折线图点描述 3235 for a_x1, b_y3, c_y4 in zip(x_axle_n1, y_yield_t1, y_yield_t2): 3236 if b_y3 < c_y4: 3237 print("# 低于卡控线: ", a_x1, file=run_log) 3238 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=12, font=font) 3239 else: 3240 # print("# 正常模组: ", a_x1) 3241 ax2.text(a_x1, b_y3, '{:.2f}%'.format(b_y3 * 100), ha='center', va='bottom', fontsize=8, font=font) 3242 ax2.text(1, c_y4, '{:.2f}%'.format(c_y4 * 100), ha='center', va='bottom', fontsize=11, font=font) # 只显示一个 3243 3244 # ====================================================================================================================# 3245 3246 # 设置x轴和y轴的标签,指明坐标含义 3247 ax1.set_xlabel(z_name_km1, fontdict={'size': 16}) 3248 # 左边-y轴为:数量模式 3249 ax1.set_ylabel('模组数量', fontdict={'size': 16}) 3250 # 右边-y轴为:百分比形式 3251 ax2.set_ylabel('百分比', fontdict={'size': 16}) 3252 3253 # 左-y轴为:刻度范围,动态调整 3254 max_value_r1 = int(max(y_total_t1) * 1.3) 3255 min_value_r1 = int(min(y_total_t2) * 0.9) 3256 if max_value_r1 < 5: 3257 max_value_r1 = 10 # 直接赋值 3258 min_value_r1 = 0 # 直接赋值 3259 ax1.set_ylim(min_value_r1, max_value_r1) 3260 # 右边-y轴为:最大值为100%,小数点2位 3261 ax2.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=2)) 3262 3263 # 设置x轴和y轴刻度字体 3264 labels2 = ax2.get_xticklabels() + ax2.get_yticklabels() 3265 [label.set_fontname('SimHei') for label in labels2] 3266 3267 # 添加图表题 plt.title('双y轴折线图') 3268 plt.title(title_up, color="red", fontsize=16) 3269 3270 # 设置轴标签颜色 3271 # ax1.tick_params('x', colors='Black') 3272 ax1.tick_params('y', colors='royalblue') 3273 ax2.tick_params('y', colors='tomato') 3274 3275 # 设置轴颜色 3276 ax1.spines['left'].set_color('royalblue') 3277 ax2.spines['left'].set_color('royalblue') 3278 ax1.spines['right'].set_color('tomato') 3279 ax2.spines['right'].set_color('tomato') 3280 3281 # 两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉 3282 ax1.spines['top'].set_visible(False) 3283 ax2.spines['top'].set_visible(False) 3284 3285 # 添加图例函数: plt.legend() 3286 # 添加图例 - 添加方向改为以下代码 3287 ax1.legend(loc='upper left') 3288 ax2.legend(loc='upper right') 3289 # 添加图例 - 将`图例合并改为以下代码 3290 # lines = line1 + line2 + line3 + line4 3291 # lines = line3 + line4 3292 # labels = [h.get_label() for h in lines] 3293 # plt.legend(lines, labels, loc='upper right') 3294 3295 # 设置中文显示 3296 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体) 3297 plt.rcParams['axes.unicode_minus'] = False 3298 3299 # 虚拟背景线 3300 plt.grid(True, linestyle="--") 3301 3302 # 展示图片 3303 # plt.show() 3304 # 显示柱状图时间,单位s 3305 time_v1 = 1 3306 while time_v1 != 0: 3307 print('显示倒计时:%d s' % time_v1) 3308 plt.pause(1) 3309 time_v1 = time_v1 - 1 3310 print('直方图显示完成') 3311 3312 # 图片保存对应文件 3313 picture_m = './6_result_ft_xx/picture/' + z_name_km1 + r".jpg" 3314 plt.savefig(picture_m) 3315 plt.draw() 3316 print('图片保存对应文件-完成') 3317 plt.close() # 关闭图表显示 3318 3319 3320 ''' 3321 # ====================================================================================================================# 3322 # 本月 --- 不良品BIN --- 测试数据汇总分布-通用模板2数据处理 3323 # ====================================================================================================================# 3324 ''' 3325 3326 3327 def defective_h2_xx(x_p1, x_p2, x_p3, y_p1, y_p2, y_p3, y_p4, z_p1, z_p2, z_p3, z_p4): 3328 print("#**** defective_h2_xx ****# >>> ", z_p1) 3329 # 按照 仅handler-marking 分类 3330 # 按照 仅lot-marking 分类 3331 # 按照 lot - handler - marking 分类 3332 single_month_z2 = defective_reorder_sub(x_p1, x_p2, x_p3, z_p1, z_p2, z_p3, z_p4) 3333 # 按照 handler - lot - marking 分类 3334 # 按照 summary表-marking 顺序 3335 3336 # 重新赋值 -single month raw data index 3337 x_axle_n1 = x_p1 3338 x_axle_n2 = x_p2 3339 x_axle_n3 = x_p3 3340 y_total_t1 = y_p1 3341 y_total_t2 = y_p2 3342 y_yield_t1 = y_p3 3343 y_yield_t2 = y_p4 3344 bin_name = z_p1 3345 month_n1 = z_p2 3346 single_month_d1 = single_month_z2 3347 raw_data_a1 = z_p4 3348 print('绘图处理: 月份< %d > 不良品< %s >' % (month_n1, bin_name)) 3349 # 获取每月函数 有效数据 x_axle_n2 3350 x_name1, x_data1 = get_data_bin_v2(x_axle_n1, single_month_d1, raw_data_a1) 3351 x_name2, x_data2 = get_data_bin_v2(x_axle_n2, single_month_d1, raw_data_a1) 3352 x_name3, x_data3 = get_data_bin_v2(x_axle_n3, single_month_d1, raw_data_a1) 3353 y_name1, y_data1 = get_data_bin_v2(y_total_t1, single_month_d1, raw_data_a1) 3354 y_name2, y_data2 = get_data_bin_v2(y_total_t2, single_month_d1, raw_data_a1) 3355 y_name3, y_data3 = get_data_bin_v2(y_yield_t1, single_month_d1, raw_data_a1) 3356 y_name4, y_data4 = get_data_bin_v2(y_yield_t2, single_month_d1, raw_data_a1) 3357 # print(x_name1, x_data1) 3358 # print(x_name2, x_data2) 3359 # print(y_name1, y_data1) 3360 # print(y_name2, y_data2) 3361 # print(y_name3, y_data3) 3362 3363 # ======================================================================================== # 3364 3365 # 整体参数配置 3366 font = FontProperties(size=10) 3367 plt.rcParams["font.sans-serif"] = ['SimHei'] 3368 plt.rcParams['axes.unicode_minus'] = False 3369 plt.rcParams['font.family'] = ['SimHei'] 3370 plt.rcParams['font.sans-serif'] = ['SimHei'] 3371 plt.rcParams['figure.figsize'] = (30, 10) 3372 plt.rc('font', family='SimHei', size=8) 3373 3374 # 创建一个图形和两个y轴 3375 fig, ax1 = plt.subplots(1, 1) # 绘制双Y轴 表示一次性在figure上创建成1*1的网格 3376 3377 # 柱状图柱子宽度 3378 bar_width = 0.4 3379 x_ticks = range(len(x_data1)) # x轴刻度位置 | 折线图x位置 3380 bar_1_x = [(ii - bar_width + 0.2) for ii in x_ticks] # 柱状图1 - x位置 3381 bar_2_x = [(ww - bar_width + 0.6) for ww in x_ticks] 3382 3383 # 设置x轴刻度字体以及方向-单刻度标签 3384 labels1 = ax1.get_xticklabels() + ax1.get_yticklabels() 3385 [label.set_fontname('SimHei') for label in labels1] 3386 # plt.xticks(x_ticks, list(x_data1), rotation=90, ) #x轴刻度位置 | 刻度标签 | 旋转90度 3387 3388 # 设置x轴刻度字体以及方向- 叠加双刻度标签 3389 labels = [] 3390 for two_m1 in range(len(x_data1)): 3391 cell_m2 = x_data3[two_m1][0:6] + ' ' + x_data2[two_m1] + ' ' + x_data1[two_m1] 3392 labels.append(cell_m2) 3393 # labels = x_ticks # 默认 3394 # print('2个叠加后的刻度标签: ',labels) # 2个叠加后的刻度标签 3395 plt.xticks(x_ticks, labels, rotation=90, ) # x轴刻度位置 | 刻度标签 | 旋转90度 3396 # 自适应调整布局+ 指定 解决X轴范围问题 3397 fig.autofmt_xdate(rotation=90) 3398 3399 # -------------------------------------------------------------------------------------- # 3400 # # 同一刻度标签标记为不同颜色 插孔法 升级-适用较为复杂的场景 第2种方案 3401 index_lot_v5 = [] 3402 for index_a in range(len(single_month_d1)): 3403 index_lot = single_month_d1[index_a] # 获取本月行号 索引值 3404 index_m1 = x_data3[index_a][0:6] # 获取本月行号 索引值 3405 index_lot_v5.append(index_m1) 3406 # all raw data 有效映射 3407 # print("all raw data 有效映射:", index_lot_v5) 3408 # 获取同一列表中相同元素,只保留一种类型 3409 one_lot_v1 = [] 3410 for v2_lot in index_lot_v5: 3411 if v2_lot not in one_lot_v1: 3412 one_lot_v1.append(v2_lot) 3413 # print('lot中唯一代表名称: ', one_lot_v1) 3414 xtick_labels = ax1.get_xticklabels() 3415 colors = ['red', 'green', 'blue', 'purple', 'orange', 'brown', 'gray', 'pink', 'cyan', 'magenta', 'yellow', 'black', ] 3416 # 利用唯一lot去适配列表lot,影射到对应刻度,根据余数去自动识别颜色,默认10种 3417 for x_color in range(len(x_data3)): 3418 # print("x_color: ",x_color,x_data3[x_color][0:6]) 3419 for one_c1 in range(len(one_lot_v1)): 3420 # print("Index:", one_c1, "Value:", one_lot_v1[one_c1]) 3421 if one_lot_v1[one_c1] == x_data3[x_color][0:6]: 3422 one_color_v1 = one_c1 % 10 3423 if one_color_v1 == 0: 3424 xtick_labels[x_color].set_color(colors[0]) 3425 elif one_color_v1 == 1: 3426 xtick_labels[x_color].set_color(colors[1]) 3427 elif one_color_v1 == 2: 3428 xtick_labels[x_color].set_color(colors[2]) 3429 elif one_color_v1 == 3: 3430 xtick_labels[x_color].set_color(colors[3]) 3431 elif one_color_v1 == 4: 3432 xtick_labels[x_color].set_color(colors[4]) 3433 elif one_color_v1 == 5: 3434 xtick_labels[x_color].set_color(colors[5]) 3435 elif one_color_v1 == 6: 3436 xtick_labels[x_color].set_color(colors[6]) 3437 elif one_color_v1 == 7: 3438 xtick_labels[x_color].set_color(colors[7]) 3439 elif one_color_v1 == 8: 3440 xtick_labels[x_color].set_color(colors[8]) 3441 elif one_color_v1 == 9: 3442 xtick_labels[x_color].set_color(colors[9]) 3443 # -------------------------------------------------------------------------------------- # 3444 3445 # 绘制双Y轴 让2个X轴一样,同时创建副坐标轴 3446 ax2 = ax1.twinx() 3447 3448 # 图例文件描述-动态变化 3449 title_up = "本月测试 " + bin_name + " 分布" 3450 legend_x3 = y_name1 3451 legend_x4 = y_name2 3452 legend_y3 = y_name3 3453 legend_y4 = y_name4 3454 3455 # ====================================================================================================================# 3456 # 绘制柱状图 3457 # bar1 = ax1.bar(bar_1_x, y_data1, label='y1轴', color='lightblue', width=0.4) 3458 # bar2 = ax1.bar(bar_2_x, y_data2, label='y2轴', color='gold', width=0.4) 3459 bar3 = ax1.bar(bar_1_x, y_data1, label=legend_x3, color='lightblue', width=bar_width, linewidth=0.2, edgecolor="white") 3460 bar4 = ax1.bar(bar_2_x, y_data2, label=legend_x4, color='gold', width=bar_width, linewidth=0.2, edgecolor="white") 3461 3462 # 绘制折线图 3463 # line1 = ax1.plot(x_data1, y_data1, label='y1轴', color='royalblue', marker='o', ls='-.') 3464 # line2 = ax2.plot(x_data1, y_data2, label='y2轴', color='tomato', marker='o', ls='--') 3465 line3 = ax2.plot(x_data1, y_data3, label=legend_y3, color='Lightgreen', marker='o', markersize='6', ls='--') 3466 line4 = ax2.plot(x_data1, y_data4, label=legend_y4, color='royalblue', marker='.', markersize='6', ls='-') 3467 3468 # ------------------------------------------------------------------------------------------------------------------- # 3469 # #TODO <特殊情况处理 -20231211> 3470 # ------------------------------------------------------------------------------------------------------------------- # 3471 legend_y5 = "sbl" # 新增sbl 卡控图例名称 3472 3473 if bin_name == "BIN3": 3474 y_data5 = [] 3475 sbl_data = 0.0021 3476 for sbl_avocado in range(len(y_data4)): 3477 y_data5.append(sbl_data) 3478 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3479 # 折线图点描述 3480 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3481 if b_y3 < b_y4: 3482 print("# BIN3 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3483 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3484 if b_y4 > c_y5: 3485 print("# BIN3 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3486 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3487 # 只显示一个 sbl 3488 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3489 3490 elif bin_name == "BIN4": 3491 y_data5 = [] 3492 sbl_data = 0.0004 3493 for sbl_avocado in range(len(y_data4)): 3494 y_data5.append(sbl_data) 3495 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3496 # 折线图点描述 3497 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3498 if b_y3 < b_y4: 3499 print("# BIN4 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3500 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3501 if b_y4 > c_y5: 3502 print("# BIN4 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3503 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3504 # 只显示一个 sbl 3505 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3506 3507 elif bin_name == "BIN5": 3508 y_data5 = [] 3509 sbl_data = 0.033 3510 for sbl_avocado in range(len(y_data4)): 3511 y_data5.append(sbl_data) 3512 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3513 # 折线图点描述 3514 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3515 if b_y3 < b_y4: 3516 print("# BIN5 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3517 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3518 if b_y4 > c_y5: 3519 print("# BIN5 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3520 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3521 # 只显示一个 sbl 3522 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3523 3524 elif bin_name == "BIN6_1": 3525 y_data5 = [] 3526 sbl_data = 0.0489 3527 for sbl_avocado in range(len(y_data4)): 3528 y_data5.append(sbl_data) 3529 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3530 # 折线图点描述 3531 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3532 if b_y3 < b_y4: 3533 print("# BIN6_1 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3534 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3535 if b_y4 > c_y5: 3536 print("# BIN6_1 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3537 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3538 # 只显示一个 sbl 3539 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3540 3541 elif bin_name == "BIN6_2": 3542 y_data5 = [] 3543 sbl_data = 0.0031 3544 for sbl_avocado in range(len(y_data4)): 3545 y_data5.append(sbl_data) 3546 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3547 # 折线图点描述 3548 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3549 if b_y3 < b_y4: 3550 print("# BIN6_2 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3551 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3552 if b_y4 > c_y5: 3553 print("# BIN6_2 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3554 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3555 # 只显示一个 sbl 3556 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3557 3558 elif bin_name == "BIN7_1": 3559 y_data5 = [] 3560 sbl_data = 0.0010 3561 for sbl_avocado in range(len(y_data4)): 3562 y_data5.append(sbl_data) 3563 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3564 # 折线图点描述 3565 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3566 if b_y3 < b_y4: 3567 print("# BIN7_1 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3568 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3569 if b_y4 > c_y5: 3570 print("# BIN7_1 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3571 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3572 # 只显示一个 sbl 3573 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3574 3575 elif bin_name == "BIN7_2": 3576 y_data5 = [] 3577 sbl_data = 0.001 3578 for sbl_avocado in range(len(y_data4)): 3579 y_data5.append(sbl_data) 3580 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3581 # 折线图点描述 3582 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3583 if b_y3 < b_y4: 3584 print("# BIN7_2 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3585 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3586 if b_y4 > c_y5: 3587 print("# BIN7_2 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3588 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3589 # 只显示一个 sbl 3590 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3591 3592 elif bin_name == "BIN7_3": 3593 y_data5 = [] 3594 sbl_data = 0.0001 3595 for sbl_avocado in range(len(y_data4)): 3596 y_data5.append(sbl_data) 3597 line5 = ax2.plot(x_data1, y_data5, label=legend_y5, color='tomato', marker='.', markersize='6', ls='-') 3598 # 折线图点描述 3599 for a_x1, b_y3, b_y4, c_y5 in zip(x_data1, y_data3, y_data4, y_data5): 3600 if b_y3 < b_y4: 3601 print("# BIN7_3 sbl卡控 fail 良率高于 实际bin fail良率: ", a_x1, file=run_log2) 3602 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3603 if b_y4 > c_y5: 3604 print("# BIN7_3 sbl卡控 fail 良率高于SBL卡控线: ", a_x1, file=run_log2) 3605 ax2.text(a_x1, b_y4, '{:.2f}%'.format(b_y4 * 100), ha='center', va='bottom', fontsize=9, font=font) 3606 # 只显示一个 sbl 3607 ax2.text(1, c_y5, '{:.2f}%'.format(c_y5 * 100), ha='center', va='bottom', fontsize=9, font=font) # 只显示一个 3608 else: 3609 print("无符合case 的 bin") 3610 # 3611 # ====================================================================================================================# 3612 3613 # 设置x轴和y轴的标签,指明坐标含义 3614 ax1.set_xlabel('lot ID', fontdict={'size': 16}) 3615 # 左边-y轴为:数量模式 3616 ax1.set_ylabel('模组数量', fontdict={'size': 16}) 3617 # 右边-y轴为:百分比形式 3618 ax2.set_ylabel('百分比', fontdict={'size': 16}) 3619 3620 # 左-y轴为:刻度范围,动态调整 3621 max_value_r1 = int(max(y_data1) * 1.3) 3622 min_value_r1 = int(min(y_data1) * 0.9) 3623 if max_value_r1 < 5: 3624 max_value_r1 = 10 # 直接赋值 3625 min_value_r1 = 0 # 直接赋值 3626 ax1.set_ylim(min_value_r1, max_value_r1) 3627 # 右边-y轴为:最大值为100%,小数点2位 3628 ax2.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=2)) 3629 3630 # 设置x轴和y轴刻度字体 3631 labels2 = ax2.get_xticklabels() + ax2.get_yticklabels() 3632 [label.set_fontname('SimHei') for label in labels2] 3633 3634 # 添加图表题 plt.title('双y轴折线图') 3635 plt.title(title_up, color="red", fontsize=16) 3636 3637 # 设置轴标签颜色 3638 # ax1.tick_params('x', colors='Black') 3639 ax1.tick_params('y', colors='royalblue') 3640 ax2.tick_params('y', colors='tomato') 3641 3642 # 设置轴颜色 3643 ax1.spines['left'].set_color('royalblue') 3644 ax2.spines['left'].set_color('royalblue') 3645 ax1.spines['right'].set_color('tomato') 3646 ax2.spines['right'].set_color('tomato') 3647 3648 # 两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉 3649 ax1.spines['top'].set_visible(False) 3650 ax2.spines['top'].set_visible(False) 3651 3652 # 添加图例函数: plt.legend() 3653 # 添加图例 - 添加方向改为以下代码 3654 ax1.legend(loc='upper left') 3655 ax2.legend(loc='upper right') 3656 # 添加图例 - 将`图例合并改为以下代码 3657 # lines = line1 + line2 + line3 + line4 3658 # lines = line3 + line4 3659 # labels = [h.get_label() for h in lines] 3660 # plt.legend(lines, labels, loc='upper right') 3661 3662 # 设置中文显示 3663 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体) 3664 plt.rcParams['axes.unicode_minus'] = False 3665 3666 # 虚拟背景线 3667 plt.grid(True, linestyle="--") 3668 3669 # 展示图片 3670 # plt.show() 3671 # 显示柱状图时间,单位s 3672 time_v1 = 1 3673 while time_v1 != 0: 3674 print('显示倒计时:%d s' % time_v1) 3675 plt.pause(1) 3676 time_v1 = time_v1 - 1 3677 print('直方图显示完成') 3678 3679 # 图片保存对应文件 3680 picture_m = './6_result_ft_xx/picture/' + bin_name + r".jpg" 3681 plt.savefig(picture_m) 3682 plt.draw() 3683 print('图片保存对应文件-完成') 3684 plt.close() # 关闭图表显示 3685 3686 3687 ''' 3688 # ====================================================================================================================# 3689 # 本月数据 -生成报告汇总 3690 # ====================================================================================================================# 3691 ''' 3692 3693 3694 def generate_report_ft_xx(z_y1): 3695 print("#**** generate_report_ft_xx ****#") 3696 month_real = str(z_y1) 3697 # ---------------------------------------------------------- # 3698 # 创建路径 / 文件夹 - 逻辑处理任意问题 3699 month_name_s = "month_" + month_real 3700 bin8_p = "\\6_result_ft_xx\\month_report\\" + month_name_s 3701 mk_file_path_v1 = os.getcwd() + bin8_p # 获取当前工作目录路径 3702 if os.path.exists(mk_file_path_v1): 3703 shutil.rmtree(mk_file_path_v1) 3704 os.mkdir(mk_file_path_v1) 3705 print("# 创建报告生成工作目录", mk_file_path_v1) 3706 mk1_file_name = mk_file_path_v1 3707 # ---------------------------------------------------------- # 3708 3709 # 拷贝文件到对应月份文件中 3710 source_folder1 = r'./6_result_ft_xx/picture' 3711 target_folder2 = mk1_file_name + '/picture' 3712 shutil.copytree(source_folder1, target_folder2) 3713 3714 # 讯芯-vi5300-ft-xx 月份+路径 3715 month_report_ft_xx(month_real, target_folder2) 3716 3717 3718 ''' 3719 # ====================================================================================================================# 3720 # month_report_ft_xx 获取html模板-ft伟测 3721 # ====================================================================================================================# 3722 ''' 3723 3724 3725 def month_report_ft_xx(z_y1, z_y2): 3726 print("************ month_report_ft_xx **********") 3727 # 获取有效值 3728 source_folder2 = z_y2 + "/月度_汇总统计结果.xlsx" 3729 # print("h获取有效的excel",source_folder2) 3730 work_book2 = openpyxl.load_workbook(source_folder2) 3731 worksheet_b2 = work_book2.active 3732 target_rows_x2 = worksheet_b2.max_row 3733 target_cols_y2 = worksheet_b2.max_column 3734 print("行列:", target_rows_x2, target_cols_y2) 3735 s_status = worksheet_b2.cell(2, 2).value 3736 s_yield = worksheet_b2.cell(2, 3).value 3737 s_limit = worksheet_b2.cell(2, 4).value 3738 s_input = worksheet_b2.cell(2, 5).value 3739 s_output = worksheet_b2.cell(2, 6).value 3740 # print(s_status, s_yield, s_limit, s_input, s_output) 3741 3742 # 3743 s_month = z_y1 3744 total_status = s_status 3745 total_yield_p = s_yield 3746 total_limit_p = s_limit 3747 total_input = s_input 3748 total_output = s_output 3749 # ----------------------------------------------------------------------------------------------- # 3750 3751 # vi5300_ft_wc_report_template 3752 # get_data_txt_v1 = open(r'C:\Users\chucheng.cao\Desktop\work\python\test_data\test_month_report_xx\note\bin1.txt', encoding='utf-8') 3753 # txt_v1 = [] 3754 # for line in get_data_txt_v1: 3755 # txt_v1.append(line.strip()) 3756 # print('添加测试:',txt_v1[0]) 3757 3758 body = [] 3759 # txt_bin1 = "BIN1" + txt_v1[0] 3760 txt_bin1 = "BIN1" 3761 txt_handler = "handler" 3762 txt_lot = "lot" 3763 txt_bin3 = "BIN3" 3764 txt_bin4 = "BIN4" 3765 txt_bin5 = "BIN5" 3766 txt_bin6_1 = "BIN6_1" 3767 txt_bin6_2 = "BIN6_2" 3768 txt_bin7_1 = "BIN7_1" 3769 txt_bin7_2 = "BIN7_2" 3770 txt_bin7_3 = "BIN7_3" 3771 txt_bin9 = "BIN9" 3772 txt_bin13 = "BIN13" 3773 txt_bin14 = "BIN14" 3774 txt_bin_vm = "BIN_vm" 3775 txt_bin_loss = "BIN_loss" 3776 # 图片路径 3777 # 当前绝对路径-建议使用相对路径 3778 source_bin1 = os.getcwd() 3779 Picture_bin1 = "\\6_result_ft_xx\\month_report" 3780 picture_bin2 = "\\month_" + s_month + "\\picture\\" 3781 Picture_bin_route = source_bin1 + Picture_bin1 + picture_bin2 3782 print("图片路径目录:", Picture_bin_route) 3783 3784 result = {'serial': "1", 3785 'SYL': total_limit_p, 3786 'Total': total_input, 3787 'BIN': total_output, 3788 'Yield': total_yield_p, 3789 'states': total_status, 3790 'Picture_bin1': Picture_bin_route + "BIN1.jpg", 'describe_bin1': txt_bin1, 3791 'Picture_handler': Picture_bin_route + "handler.jpg", 'describe_handler': txt_handler, 3792 'Picture_lot': Picture_bin_route + "lot.jpg", 'describe_lot': txt_lot, 3793 'Picture_bin3': Picture_bin_route + "BIN3.jpg", 'describe_bin3': txt_bin3, 3794 'Picture_bin4': Picture_bin_route + "BIN4.jpg", 'describe_bin4': txt_bin4, 3795 'Picture_bin5': Picture_bin_route + "BIN5.jpg", 'describe_bin5': txt_bin5, 3796 'Picture_bin6_1': Picture_bin_route + "BIN6_1.jpg", 'describe_bin6': txt_bin6_1, 3797 'Picture_bin6_2': Picture_bin_route + "BIN6_2.jpg", 'describe_bin6_2': txt_bin6_2, 3798 'Picture_bin7_1': Picture_bin_route + "BIN7_1.jpg", 'describe_bin7_1': txt_bin7_1, 3799 'Picture_bin7_2': Picture_bin_route + "BIN7_2.jpg", 'describe_bin7_2': txt_bin7_2, 3800 'Picture_bin7_3': Picture_bin_route + "BIN7_3.jpg", 'describe_bin7_3': txt_bin7_3, 3801 } 3802 body.append(result) 3803 start_monthly = "2023." + str(s_month) + ".1" 3804 stop_monthly = "2023." + str(s_month) + ".30" 3805 # html_vi5300_ft_wc(body, start_monthly, stop_monthly, s_month) 3806 3807 env = Environment(loader=FileSystemLoader(r'./6_result_ft_xx/month_report/')) 3808 test_report = env.get_template('vi5300_ft_xx_report_template.html') 3809 monthly_V12_data = "./6_result_ft_xx/month_report/month_" + s_month + "/report_" + s_month + "monthly_result.html" 3810 with open(monthly_V12_data, 'w+') as fout: 3811 html_content = test_report.render(start_time=start_monthly, stop_time=stop_monthly, body=body) 3812 fout.write(html_content) 3813 3814 # 将HTML文件转换为PDF文件 3815 # pdfkit.from_file( 'report_11monthly_result.html', 'report_11monthly_result.pdf') 3816 # --------------------------------------------------------------------------------------------------------------# 3817 datetime_object_21 = datetime.datetime.now() 3818 print("datetime_object_21 :", datetime_object_21) 3819 3820 3821 ''' 3822 #---------------------------------------------------------------------------------------------------------------# 3823 # sop_s1_s1 3824 #---------------------------------------------------------------------------------------------------------------# 3825 ''' 3826 3827 3828 def sop_s1_s1(): 3829 global run_log 3830 run_log = open('./4_result_ft/picture/run_data_log.txt', 'w') 3831 # C:\Users\chucheng.cao\Desktop\work\python\test_data\handle_vi5300_ft_wc\1_version\20231212-1015-完成报告生成\4_result_ft\picture 3832 print("读取summary表生成可视化图表", file=run_log) 3833 input_path_t0 = r'./3_summary_ft' # path定义要获取的文件名称的目录 3834 print("定义要获取的文件名称的目录: ", input_path_t0, file=run_log) 3835 all_data = read_excel(input_path_t0) # 读取文件,并且获取所有内容 3836 vi5300_ft_wc_handle_v1(all_data) 3837 run_log.close() 3838 3839 3840 ''' 3841 #---------------------------------------------------------------------------------------------------------------# 3842 # sop_s2_s1 3843 #---------------------------------------------------------------------------------------------------------------# 3844 ''' 3845 3846 3847 def sop_s2_s1(): 3848 global run_log2 3849 run_log2 = open('./6_result_ft_xx/picture/run_data_log2.txt', 'w') 3850 print("读取summary表生成可视化图表", file=run_log2) 3851 3852 input_path_xx = r'./5_summary_ft_xx' # path定义要获取的文件名称的目录 3853 print("定义要获取的文件名称的目录: ", input_path_xx, file=run_log2) 3854 3855 file_name_list = os.listdir(input_path_xx) # os.listdir()方法获取文件夹名字,返回数组 3856 print("获取文件夹列表:\n", file_name_list) 3857 3858 # 拼接路径 -- 仅仅获取第一个 3859 input_path_s2 = input_path_xx + '\\' + file_name_list[0] 3860 # 读取文件 3861 work_pd2 = pd.read_excel(io=input_path_s2, sheet_name=0, header=None) # 3862 pd.set_option('display.max_columns', None) # 显示完整的行 3863 pd.set_option('display.max_rows', None) # 显示完整的列 3864 pd.set_option('display.expand_frame_repr', False) # 设置不折叠数据 3865 pd.set_option('display.float_format', lambda x: '%.2f' % x) # 设置不以科学计数法显示 3866 # print("显示读取excel全部内容: \n",work_pd2) 3867 3868 vi5300_ft_xx_handle_v2(work_pd2) 3869 run_log2.close() 3870 3871 3872 ''' 3873 #==================================================================================================================# 3874 # 3875 #main 3876 # 3877 #==================================================================================================================# 3878 ''' 3879 if __name__ == '__main__': 3880 print("开始测试") 3881 3882 # sop_s1_s1() 3883 # sop_s2_s1() 3884 3885 run_big_cycle1 = 1 3886 while run_big_cycle1: 3887 print("请选择以下场景: [提示 0:表示退出]") 3888 print("scenario 1: VI5300 FT 伟测(wc) summary表自动生成报表 ") 3889 print("scenario 2: VI5300 FT 讯芯(xx) summary表自动生成报表") 3890 print(">>> 请输入功能:") 3891 function_order = input() 3892 if function_order == "0": 3893 print("退出运行") 3894 run_big_cycle1 = 0 3895 elif function_order == "1": 3896 print("scenario 1") 3897 run_s1 = 1 3898 while run_s1: 3899 print("scenario_1场景: [提示 0:表示退出]") 3900 print("scenario_1 1: VI5300 FT 伟测(wc) summary表自动生成报表 - auto·") 3901 print(">>> 请输入功能:") 3902 function_order_s1 = input() 3903 if function_order_s1 == "0": 3904 print("退出运行") 3905 run_s1 = 0 3906 elif function_order_s1 == "1": 3907 sop_s1_s1() 3908 print("完成s1 1功能") 3909 else: 3910 print("输入无效数值!") 3911 3912 print("继续执行: y 返回上一级:b") 3913 mean_m = input() 3914 if mean_m == "b": 3915 function_order_s1 = "0" 3916 run_s1 = 0 3917 # --------------------------------------------- 2 # 3918 elif function_order == "2": 3919 print("scenario 2") 3920 run_s2 = 1 3921 while run_s2: 3922 print("scenario_2场景: [提示 0:表示退出]") 3923 print("scenario_2 1: VI5300 FT 讯芯(xx) summary表自动生成报表 -auto.") 3924 print(">>> 请输入功能:") 3925 function_order_s2 = input() 3926 if function_order_s2 == "0": 3927 print("退出运行") 3928 run_s2 = 0 3929 elif function_order_s2 == "1": 3930 sop_s2_s1() 3931 print("完成s2 1功能") 3932 else: 3933 print("输入无效数值!") 3934 3935 print("继续执行: y 返回上一级:b") 3936 mean_m = input() 3937 if mean_m == "b": 3938 function_order_s2 = "0" 3939 run_s2 = 0 3940 # --------------------------------------------- 2 # 3941 else: 3942 print("没有此功能请重新选择")
#---- code end ----#
交互界面套用固定模版复用
愿:
可以帮助到您,
感谢您的阅读。