| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- import os
- import pandas as pd
- import numpy as np
- import plotly.graph_objects as go
- from plotly.subplots import make_subplots
- import seaborn as sns
- import matplotlib.pyplot as plt
- from matplotlib.ticker import MultipleLocator
- from windrose import WindroseAxes
- from behavior.analyst import Analyst
- from utils.directoryUtil import DirectoryUtil as dir
- from algorithmContract.confBusiness import *
- from matplotlib.cm import get_cmap
- from matplotlib.colors import ListedColormap
- class WinRoseOfTurbineAnalyst(Analyst):
- """
- 风电机组变桨-功率分析
- """
- def typeAnalyst(self):
- return "wind_rose_turbine"
- def turbinesAnalysis(self, dataFrameMerge, outputAnalysisDir, confData: ConfBusiness):
- self.windRoseAnalysis(dataFrameMerge, outputAnalysisDir, confData)
- def windRoseAnalysis(self, dataFrameMerge:pd.DataFrame, outputAnalysisDir, confData: ConfBusiness):
- # 检查所需列是否存在
- required_columns = {confData.field_wind_dir,confData.field_wind_speed}
- if not required_columns.issubset(dataFrameMerge.columns):
- raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}")
-
- # 风速区间
- bins = [0, 3, 6, 9, np.inf]
- speed_labels = ['[0,3)', '[3,6)', '[6,9)', '>=9']
- # 准备颜色映射
- colors = plt.cm.Blues(np.linspace(0, 1, len(speed_labels)))
- cmap = ListedColormap(colors)
- # 将风向按照22.5度一个间隔进行分组
- wind_directions = np.arange(0, 360, 22.5)
- # 按设备名分组数据
- grouped = dataFrameMerge.groupby(Field_NameOfTurbine)
- print("self.ratedPower {}".format(confData.rated_power))
- # 遍历每个设备并绘制图
- for name, group in grouped:
- # 对风速进行分箱处理,但不添加到DataFrame中
- speed_bins = pd.cut(group[confData.field_wind_speed], bins=bins, labels=speed_labels)
-
- # 将风向按照22.5度一个间隔进行分组
- wind_directions = np.arange(0, 360, 22.5)
- group['风向分组'] = pd.cut(group[confData.field_wind_dir], bins=wind_directions, labels=wind_directions[:-1])
-
- # 绘制风玫瑰图
- fig, ax = plt.subplots(figsize=(8, 8), subplot_kw={'polar': True})
-
- # 为每个风速区间绘制风向的条形图,并添加图例
- for i, (label, color) in enumerate(zip(speed_labels, colors)):
- # 筛选出当前风速区间的数据
- subset = group[speed_bins == label]
- # 计算每个风向分组的频数
- counts = subset['风向分组'].value_counts().reindex(wind_directions[:-1], fill_value=0)
- # 绘制条形图,并添加标签用于图例
- bar = ax.bar(counts.index * np.pi / 180, counts.values, color=cmap(i), alpha=0.75, width=(22.5 * np.pi / 180), label=label)
-
- # 设置标题和标签
- ax.set_title(f"Wind Rose {name}", va='top')
- ax.set_theta_zero_location('N') # 设置0度位置为北
- ax.set_theta_direction(-1) # 设置角度方向为顺时针
- ax.set_yticklabels([]) # 不显示y轴刻度标签
- ax.set_xticks(wind_directions * np.pi / 180) # 设置x轴刻度
- ax.set_xticklabels(['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']) # 设置x轴刻度标签为方向
-
- # 添加图例,并设置位置以避免与图形重叠
- ax.legend(title='Wind Speed', bbox_to_anchor=(1.1, 1), loc='center left', borderaxespad=0.)
- # 保存图像并关闭绘图窗口
- output_file = os.path.join(outputAnalysisDir, f"{name}.png")
- plt.savefig(output_file, bbox_inches='tight', dpi=120)
- plt.close()
|