import os import pandas as pd import numpy as np import plotly.graph_objects as go import plotly.express as px from plotly.subplots import make_subplots from behavior.analystNotFilter import AnalystNotFilter from utils.directoryUtil import DirectoryUtil as dir import matplotlib.pyplot as plt from algorithmContract.confBusiness import * from algorithmContract.contract import Contract class WindSpeedFrequencyAnalyst(AnalystNotFilter): def typeAnalyst(self): return "wind_speed_frequency" # def filterCommon(self,dataFrame:pd.DataFrame, conf: Contract): # return dataFrame def turbinesAnalysis(self, outputAnalysisDir, conf: Contract, turbineCodes): dictionary=self.processTurbineData(turbineCodes,conf,[Field_DeviceCode,Field_Time,Field_WindSpeed,Field_ActiverPower]) dataFrameMerge=self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self) return self.windRoseAnalysis(dataFrameMerge, outputAnalysisDir, conf) def windRoseAnalysis(self, dataFrameMerge: pd.DataFrame, outputAnalysisDir, conf: Contract): # 检查所需列是否存在 required_columns = {Field_NameOfTurbine, Field_WindSpeed} if not required_columns.issubset(dataFrameMerge.columns): raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}") wind_speed_bins = np.arange(0, 26, 0.5) # x轴风速范围 ,间隔0.5 # 按设备名分组数据 grouped = dataFrameMerge.groupby([Field_NameOfTurbine, Field_CodeOfTurbine]) result_rows = [] for name, group in grouped: # 2. 计算风速频率 # 首先,我们需要确定风速的范围并计算每个风速的频数 # wind_speeds = group[Field_WindSpeed].unique() # 计算风速频率,确保频率没有零值(用很小的数代替零) wind_speed_freq = np.histogram(group[Field_WindSpeed], bins=wind_speed_bins)[0] wind_speed_freq = np.maximum(wind_speed_freq, 0.01) / len(group[Field_WindSpeed]) * 100 # 3. & 4. 确定y轴风速频率的范围和间隔(这里直接计算了频率,所以不需要手动设置间隔) # 我们已经计算了风速频率,因此不需要再手动设置y轴的间隔和范围 # 5. 使用plotly绘制风速频率分布柱状图 # 为了使用plotly绘制柱状图,我们需要将风速范围的中点作为x轴的值 x_values = (wind_speed_bins[:-1] + wind_speed_bins[1:]) / 2 # 创建柱状图 fig = px.bar(x=x_values, y=wind_speed_freq) # 更新图形的布局 fig.update_layout( title={ 'text': f'风速频率: {name[0]}', # 'y': 0.95, 'x': 0.5, 'xanchor': 'center', 'yanchor': 'top' }, xaxis=dict( title='风速 (m/s)', showgrid=True, range=[0, 26], dtick=1, tickangle=-45 ), yaxis=dict( title='频率 (%)', showgrid=True, # range=[0, 1], ), margin=dict(t=50, b=10) # t为顶部(top)间距,b为底部(bottom)间距 ) # # 更新x轴和y轴的范围和标签 # fig.update_yaxes(range=[0, max(wind_speed_freq) * 1.1 if max(wind_speed_freq) > 0 else 0.2], title='Frequency') # Save plot filePathOfImage = os.path.join(outputAnalysisDir, f"{name[0]}.png") fig.write_image(filePathOfImage, scale=3) filePathOfHtml = os.path.join(outputAnalysisDir, f"{name[0]}.html") fig.write_html(filePathOfHtml) result_rows.append({ Field_Return_TypeAnalyst: self.typeAnalyst(), Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID, Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum, Field_CodeOfTurbine: name[1], 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: name[1], Field_Return_FilePath: filePathOfHtml, Field_Return_IsSaveDatabase: True }) result_df = pd.DataFrame(result_rows) return result_df