powerScatterAnalyst.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import os
  2. from datetime import datetime
  3. import pandas as pd
  4. import numpy as np
  5. import pandas as pd
  6. import plotly.graph_objects as go
  7. from plotly.subplots import make_subplots
  8. from behavior.analyst import Analyst
  9. from utils.directoryUtil import DirectoryUtil as dir
  10. from algorithmContract.confBusiness import *
  11. import plotly.express.colors as px_colors
  12. class PowerScatterAnalyst(Analyst):
  13. """
  14. 风电机组功率曲线散点分析。
  15. 秒级scada数据运算太慢,建议使用分钟级scada数据
  16. """
  17. def typeAnalyst(self):
  18. return "power_scatter"
  19. def turbinesAnalysis(self, dataFrameMerge, outputAnalysisDir, confData: ConfBusiness):
  20. if len(dataFrameMerge) <= 0:
  21. print("After screening for blade pitch angle less than the configured value, plot power curve scatter points without data")
  22. return
  23. dataFrameGuaranteePowerCurve = self.dataFrameContractOfTurbine
  24. self.drawOfPowerCurveScatter(
  25. dataFrameMerge, outputAnalysisDir, confData, dataFrameGuaranteePowerCurve)
  26. def contractGuaranteePowerCurveData(self, csvPowerCurveFilePath):
  27. dataFrameGuaranteePowerCurve = pd.read_csv(
  28. csvPowerCurveFilePath, encoding=charset_unify)
  29. return dataFrameGuaranteePowerCurve
  30. def drawOfPowerCurveScatter(self, dataFrame: pd.DataFrame, outputAnalysisDir, confData: ConfBusiness, dataFrameGuaranteePowerCurve: pd.DataFrame):
  31. """
  32. 绘制风速-功率分布图并保存为文件。
  33. 参数:
  34. dataFrameMerge (pd.DataFrame): 包含数据的DataFrame,需要包含设备名、风速和功率列。
  35. csvPowerCurveFilePath (str): 功率曲线文件路径。
  36. outputAnalysisDir (str): 分析输出目录。
  37. confData (ConfBusiness): 配置
  38. """
  39. # 按设备名分组数据
  40. colorsList = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd',
  41. '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf', '#aec7e8', '#ffbb78']
  42. grouped = dataFrame.groupby(Field_NameOfTurbine)
  43. # 遍历每个设备的数据
  44. for name, group in grouped:
  45. # 创建颜色映射,将每个年月映射到一个唯一的颜色
  46. unique_months = group[Field_YearMonth].unique()
  47. colors = [
  48. colorsList[i % 12] for i in range(len(unique_months))]
  49. color_map = dict(zip(unique_months, colors))
  50. # 使用go.Scatter3d创建3D散点图
  51. trace = go.Scatter3d(
  52. x=group[confData.field_wind_speed],
  53. y=group[Field_YearMonth],
  54. z=group[confData.field_power],
  55. mode='markers',
  56. marker=dict(
  57. color=[color_map[month]
  58. for month in group[Field_YearMonth]],
  59. size=1.5,
  60. line=dict(
  61. color='rgba(0, 0, 0, 0)', # 设置边框颜色为透明,以去掉白色边框
  62. width=0 # 设置边框宽度为0,进一步确保没有边框
  63. ),
  64. opacity=0.8 # 调整散点的透明度,增加透视效果
  65. )
  66. )
  67. # 创建图形
  68. fig = go.Figure(data=[trace])
  69. # 更新图形的布局
  70. fig.update_layout(
  71. title={
  72. "text": f'Monthly power 3D scatter plot {name}',
  73. "x": 0.5
  74. },
  75. scene=dict(
  76. xaxis=dict(title='Wind Speed'),
  77. yaxis=dict(
  78. title='Time',
  79. tickmode='array',
  80. tickvals=unique_months,
  81. ticktext=unique_months,
  82. categoryorder='category ascending'
  83. ),
  84. zaxis=dict(
  85. title='Power',
  86. dtick=confData.graphSets["activePower"]["step"] if not self.common.isNone(
  87. confData.graphSets["activePower"]) and not self.common.isNone(
  88. confData.graphSets["activePower"]["step"]) else 250,
  89. range=[confData.graphSets["activePower"]["min"] if not self.common.isNone(
  90. confData.graphSets["activePower"]["min"]) else 0, confData.graphSets["activePower"]["max"] if not self.common.isNone(confData.graphSets["activePower"]["max"]) else confData.rated_power*1.2],
  91. )
  92. ),
  93. scene_camera=dict(
  94. up=dict(x=0, y=0, z=1), # 保持相机向上方向不变
  95. center=dict(x=0, y=0, z=0), # 保持相机中心位置不变
  96. eye=dict(x=-1.8, y=-1.8, z=1.2) # 调整eye属性以实现水平旋转180°
  97. ),
  98. margin=dict(t=50, b=10) # t为顶部(top)间距,b为底部(bottom)间距
  99. )
  100. # 保存图像
  101. outputFileHtml = os.path.join(
  102. outputAnalysisDir, "{}.html".format(name))
  103. fig.write_html(outputFileHtml)