windRoseOfTurbine.py 3.9 KB

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