import os import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import plotly.graph_objects as go from behavior.analystExcludeRatedPower import AnalystExcludeRatedPower from utils.directoryUtil import DirectoryUtil as dir from algorithmContract.confBusiness import * class TSRTrendAnalyst(AnalystExcludeRatedPower): """ 风电机组叶尖速比时序分析 """ def typeAnalyst(self): return "tsr_trend" def turbinesAnalysis(self, dataFrameMerge, outputAnalysisDir, confData: ConfBusiness): self.drawTSRTrend(dataFrameMerge, outputAnalysisDir, confData) def drawTSRTrend(self,dataFrameMerge:pd.DataFrame, outputAnalysisDir, confData: ConfBusiness): # 检查所需列是否存在 required_columns = {Field_TSR, Field_YearMonthDay} if not required_columns.issubset(dataFrameMerge.columns): raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}") # 按设备名分组数据 grouped = dataFrameMerge.groupby(Field_NameOfTurbine) for name, group in grouped: # 计算四分位数和IQR Q1 = group[Field_TSR].quantile(0.15) Q3 = group[Field_TSR].quantile(0.90) IQR = Q3 - Q1 # 定义离群值的范围 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR # 筛选掉离群值 filtered_group = group[(group[Field_TSR] >= lower_bound) & (group[Field_TSR] <= upper_bound)] # 创建箱线图 fig = go.Figure() fig.add_trace(go.Box( x=filtered_group[Field_YearMonthDay], # 设置x轴数据为日期 y=filtered_group[Field_TSR], # 设置y轴数据为风能利用系数 # boxpoints='outliers', # 显示异常值(偏离值),不显示数据的所有点(只显示异常值) boxpoints=False, # 不显示偏离值 marker=dict(color='lightgoldenrodyellow', size=1), # 设置偏离值的颜色和大小 line=dict(color='lightgray', width=2), # 设置箱线和须线的颜色为灰色,粗细为2 fillcolor='rgba(200, 200, 200, 0.5)', # 设置箱体的填充颜色和透明度 name='TSR' # 图例名称 )) # 对于每个箱线图的中位数,绘制一个蓝色点 medians = filtered_group.groupby(filtered_group[Field_YearMonthDay])[Field_TSR].median() fig.add_trace(go.Scatter( x=medians.index, y=medians.values, mode='markers', marker=dict(color='orange', size=3), name='Median TSR' # 中位数标记的图例名称 )) # 设置图表的标题和轴标签 fig.update_layout( title={ 'text': f'TSR Trend Turbine Name {name}', 'x':0.5, }, xaxis_title='time', yaxis_title='TSR', xaxis=dict( tickmode='auto', # 自动设置x轴刻度,以适应日期数据 tickformat='%Y-%m-%d', # 设置x轴时间格式 showgrid=True, # 显示网格线 gridcolor='lightgray', # setting y-axis gridline color to black tickangle=-45, linecolor='black', # 设置y轴坐标系线颜色为黑色 ticklen=5, # 设置刻度线的长度 ), yaxis=dict( dtick=confData.graphSets["tsr"]["step"] if not self.common.isNone( confData.graphSets["tsr"]["step"]) else 5, # 设置y轴刻度间隔为0.1 range=[confData.graphSets["tsr"]["min"] if not self.common.isNone( confData.graphSets["tsr"]["min"]) else 0, confData.graphSets["tsr"]["max"] if not self.common.isNone(confData.graphSets["tsr"]["max"]) else 20], # 设置y轴的范围从0到1 showgrid=True, # 显示网格线 gridcolor='lightgray', # setting y-axis gridline color to black linecolor='black', # 设置y轴坐标系线颜色为黑色 ticklen=5, # 设置刻度线的长度 ), paper_bgcolor='white', # 设置纸张背景颜色为白色 plot_bgcolor='white', # 设置图表背景颜色为白色 margin=dict(t=50, b=10) # t为顶部(top)间距,b为底部(bottom)间距 ) # 保存图像 output_file = os.path.join(outputAnalysisDir, f"{name}.png") fig.write_image(output_file, scale=2)