import os import pandas as pd import plotly.express as px from algorithmContract.confBusiness import * from algorithmContract.contract import Contract from behavior.analystNotFilter import AnalystNotFilter class WindSpeedAnalyst(AnalystNotFilter): def typeAnalyst(self): return "wind_speed" def turbinesAnalysis(self, outputAnalysisDir, conf: Contract, turbineCodes): dictionary=self.processTurbineData(turbineCodes,conf,[Field_DeviceCode,Field_Time,Field_WindSpeed,Field_ActiverPower]) turbineInfos = self.common.getTurbineInfos(conf.dataContract.dataFilter.powerFarmID, turbineCodes, self.turbineInfo) dataFrameMerge=self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self) return self.drawWindSpeedAnalysis(dataFrameMerge, turbineInfos,outputAnalysisDir, conf) def drawWindSpeedAnalysis(self, dataFrameMerge: pd.DataFrame, turbineModelInfo: pd.Series, outputAnalysisDir, conf: Contract): # 检查所需列是否存在 required_columns = {Field_NameOfTurbine, Field_WindSpeed} if not required_columns.issubset(dataFrameMerge.columns): raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}") # 确保'风速'列是数值类型 dataFrameMerge[Field_WindSpeed] = pd.to_numeric( dataFrameMerge[Field_WindSpeed], errors='coerce') # 计算每个turbine_name的平均风速 average_wind_speed = dataFrameMerge.groupby(Field_NameOfTurbine)[ Field_WindSpeed].mean().reset_index() # 使用plotly绘制柱状图 fig = px.bar(average_wind_speed, x=Field_NameOfTurbine, y=Field_WindSpeed, title=f'机组平均风速') # 更新x轴和y轴的标签 fig.update_xaxes(title_text='机组', tickangle=-45) fig.update_yaxes(title_text='平均风速 (m/s)') # 如果需要进一步调整标题样式或位置(尽管默认情况下标题是居中的) # 可以使用 update_layout 来设置标题的 x 坐标(xanchor)为 'center' 来确保居中 fig.update_layout(title_x=0.5) # 设置标题的x位置为图的中心 engineTypeCode = turbineModelInfo.get(Field_MillTypeCode, "") if isinstance(engineTypeCode, pd.Series): engineTypeCode = engineTypeCode.iloc[0] engineTypeName = turbineModelInfo.get(Field_MachineTypeCode, "") if isinstance(engineTypeName, pd.Series): engineTypeName = engineTypeName.iloc[0] # 构建最终的JSON对象 json_output = { "analysisTypeCode": "风速均值分析", "engineCode": engineTypeCode, "engineTypeName": engineTypeName, "xaixs": "机组", "yaixs": "平均风速(m/s)", "data": [{ "engineName":"", "engineCode": "", "title": f'机组平均风速', "xData": average_wind_speed[Field_NameOfTurbine].tolist(), "yData": average_wind_speed[Field_WindSpeed].tolist(), }] } # Save plot # filePathOfImage = os.path.join( # outputAnalysisDir, f"WindSpeedAvg_Turbines.png") # fig.write_image(filePathOfImage, scale=3) # filePathOfHtml = os.path.join( # outputAnalysisDir, f"WindSpeedAvg_Turbines.html") # fig.write_html(filePathOfHtml) # 将JSON对象保存到文件 output_json_path = os.path.join(outputAnalysisDir, f"WindSpeedAvg_Turbines.json") with open(output_json_path, 'w', encoding='utf-8') as f: import json json.dump(json_output, f, ensure_ascii=False, indent=4) result_rows = [] # result_rows.append({ # Field_Return_TypeAnalyst: self.typeAnalyst(), # Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID, # Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum, # Field_CodeOfTurbine: "total", # Field_Return_FilePath: filePathOfImage, # Field_Return_IsSaveDatabase: False # }) result_rows.append({ Field_Return_TypeAnalyst: self.typeAnalyst(), Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID, Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum, Field_CodeOfTurbine: "total", Field_MillTypeCode: 'total', Field_Return_FilePath: output_json_path, Field_Return_IsSaveDatabase: True }) result_df = pd.DataFrame(result_rows) return result_df