import os import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from .analyst import Analyst from .utils.directoryUtil import DirectoryUtil as dir from confBusiness import ConfBusiness class TSRTrendAnalyst(Analyst): """ 风电机组叶尖速比时序分析 """ def typeAnalyst(self): return "tsr_trend" def turbineAnalysis(self, dataFrame, outputAnalysisDir, outputFilePath, confData: ConfBusiness, turbineName): self.tsr_trend(dataFrame, outputFilePath, confData.field_turbine_time, confData.field_wind_speed, confData.field_rotor_speed, confData.field_power, confData.field_pitch_angle1, confData.rotor_diameter) def tsr_trend(self, dataFrame, output_path, field_time, field_wind_speed, field_rotor_speed, field_power_active, field_angle_pitch, rotor_diameter): # Convert time column to datetime and extract date dataFrame[field_time] = pd.to_datetime( dataFrame[field_time], format='%Y-%m-%d %H:%M:%S') dataFrame['time_day'] = dataFrame[field_time].dt.date # Calculate 'tsr' dataFrame['wind_speed'] = dataFrame[field_wind_speed].astype(float) dataFrame['rotor_speed'] = dataFrame[field_rotor_speed].astype(float) rotor_diameter = pd.to_numeric(rotor_diameter, errors='coerce') dataFrame['tsr'] = (dataFrame['rotor_speed'] * 0.104667 * (rotor_diameter / 2)) / dataFrame['wind_speed'] # Group by day and aggregate grouped = dataFrame.groupby('time_day').agg({ field_time: 'min', 'wind_speed': 'mean', 'rotor_speed': 'mean', 'tsr': ['mean', 'max', 'min'] }).reset_index() # Rename columns post-aggregation grouped.columns = ['time_day', 'time_', 'wind_speed', 'rotor_speed', 'tsr', 'tsr_max', 'tsr_min'] # Sort by day grouped.sort_values('time_day', inplace=True) # Write to CSV grouped.to_csv(output_path, index=False) def turbinesAnalysis(self, dataFrameMerge, outputAnalysisDir, confData: ConfBusiness): self.plot_tsr_trend(outputAnalysisDir, confData.farm_name) def plot_tsr_trend(self, csvFileDirOfCp, farm_name, encoding='utf-8'): """ Plot TSR trend from CSV files in a given input path and save the plots to an output path. Parameters: - csvFileDirOfCp: str, path to the directory containing input CSV files. - farm_name: str, name of the wind farm. - encoding: str, encoding of the input CSV files. Defaults to 'utf-8'. """ field_Name_Turbine = "turbine_name" file_time = 'time_day' y_name = 'tsr' y_min = 'tsr_min' y_max = 'tsr_max' split_way = '_tsr_trend.csv' # Set seaborn palette sns.set_palette('deep') # Iterate over the files in the input directory for root, dir_names, file_names in dir.list_directory(csvFileDirOfCp): for file_name in file_names: if not file_name.endswith(".csv"): continue try: print(os.path.join(root, file_name)) data = pd.read_csv(os.path.join( root, file_name), encoding=encoding) # Convert the time column to datetime data.loc[:, file_time] = pd.to_datetime( data.loc[:, file_time]) # Calculate min and max TSR values data[y_min] = data[y_name] - data[y_min] data[y_max] = data[y_max] - data[y_name] # Split the file name to get the output name turbine_name = file_name.split(split_way)[0] # 添加设备名作为新列 data[field_Name_Turbine] = turbine_name # Plot the TSR trend with error bars fig, ax = plt.subplots() ax.errorbar(x=data[file_time], y=data[y_name], yerr=[data[y_min], data[y_max]], fmt='o', capsize=4, elinewidth=2, ecolor='lightgrey', mfc='dodgerblue') # Set axis labels, limits, and title ax.set_xlabel('time') ax.set_ylabel('TSR') # ax.set_ylim(0, 16) ax.set_title('turbine_name={}'.format(turbine_name)) # Save the plot to the output path plt.savefig(os.path.join(csvFileDirOfCp, "{}.png".format( turbine_name)), bbox_inches='tight', dpi=120) plt.close(fig) except Exception as e: print(f"An error occurred while processing file {file_name}: {e}")