cpTrendAnalyst.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import os
  2. import pandas as pd
  3. import numpy as np
  4. from plotly.subplots import make_subplots
  5. import plotly.graph_objects as go
  6. import matplotlib.pyplot as plt
  7. from matplotlib.ticker import MultipleLocator
  8. from behavior.analystExcludeRatedPower import AnalystExcludeRatedPower
  9. from utils.directoryUtil import DirectoryUtil as dir
  10. from algorithmContract.confBusiness import *
  11. class CpTrendAnalyst(AnalystExcludeRatedPower):
  12. """
  13. 风电机组风能利用系数时序分析
  14. """
  15. def typeAnalyst(self):
  16. return "cp_trend"
  17. def turbinesAnalysis(self, dataFrameMerge: pd.DataFrame, outputAnalysisDir, confData: ConfBusiness):
  18. self.drawCpTrend(dataFrameMerge, outputAnalysisDir, confData)
  19. def drawCpTrend(self, dataFrameMerge: pd.DataFrame, outputAnalysisDir, confData: ConfBusiness):
  20. # 检查所需列是否存在
  21. required_columns = {Field_Cp, Field_YearMonthDay}
  22. if not required_columns.issubset(dataFrameMerge.columns):
  23. raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}")
  24. # 按设备名分组数据
  25. grouped = dataFrameMerge.groupby(Field_NameOfTurbine)
  26. for name, group in grouped:
  27. # # 计算四分位数和IQR
  28. Q1 = group[Field_Cp].quantile(0.25)
  29. Q3 = group[Field_Cp].quantile(0.85)
  30. IQR = Q3 - Q1
  31. # 定义离群值的范围
  32. lower_bound = Q1 - 1.5 * IQR
  33. upper_bound = Q3 + 1.5 * IQR
  34. # 筛选掉离群值
  35. filtered_group = group[(group[Field_Cp] >= lower_bound) & (
  36. group[Field_Cp] <= upper_bound)]
  37. # 创建箱线图
  38. fig = go.Figure()
  39. fig.add_trace(go.Box(
  40. x=filtered_group[Field_YearMonthDay], # 设置x轴数据为日期
  41. y=filtered_group[Field_Cp], # 设置y轴数据为风能利用系数
  42. # boxpoints='outliers', # 显示异常值(偏离值),不显示数据的所有点(只显示异常值)
  43. boxpoints=False, # 不显示偏离值
  44. marker=dict(color='lightgoldenrodyellow',
  45. size=1), # 设置偏离值的颜色和大小
  46. line=dict(color='lightgray', width=2), # 设置箱线和须线的颜色为灰色,粗细为2
  47. fillcolor='rgba(200, 200, 200, 0.5)', # 设置箱体的填充颜色和透明度
  48. name='Cp' # 图例名称
  49. ))
  50. # 对于每个箱线图的中位数,绘制一个蓝色点
  51. medians = filtered_group.groupby(filtered_group[Field_YearMonthDay])[
  52. Field_Cp].median()
  53. fig.add_trace(go.Scatter(
  54. x=medians.index,
  55. y=medians.values,
  56. mode='markers',
  57. marker=dict(color='orange', size=3),
  58. name='Median Cp' # 中位数标记的图例名称
  59. ))
  60. # 设置图表的标题和轴标签
  61. fig.update_layout(
  62. title={
  63. 'text': f'Cp Trend Turbine Name {name}',
  64. # 'y': 1,
  65. 'x': 0.5,
  66. # 'xanchor': 'center',
  67. # 'yanchor': 'top'
  68. },
  69. xaxis_title='Time',
  70. yaxis_title='Cp',
  71. xaxis=dict(
  72. tickmode='auto', # 自动设置x轴刻度,以适应日期数据
  73. tickformat='%Y-%m-%d', # 设置x轴时间格式
  74. showgrid=True, # 显示网格线
  75. gridcolor='lightgray', # setting y-axis gridline color to black
  76. tickangle=-45,
  77. linecolor='black', # 设置y轴坐标系线颜色为黑色
  78. ticklen=5, # 设置刻度线的长度
  79. ),
  80. yaxis=dict(
  81. dtick=confData.graphSets["cp"]["step"] if not self.common.isNone(
  82. confData.graphSets["cp"]["step"]) else 0.5, # 设置y轴刻度间隔为0.1
  83. range=[confData.graphSets["cp"]["min"] if not self.common.isNone(
  84. confData.graphSets["cp"]["min"]) else 0, confData.graphSets["cp"]["max"] if not self.common.isNone(confData.graphSets["cp"]["max"]) else 2], # 设置y轴的范围从0到1
  85. showgrid=True, # 显示网格线
  86. gridcolor='lightgray', # setting y-axis gridline color to black
  87. linecolor='black', # 设置y轴坐标系线颜色为黑色
  88. ticklen=5, # 设置刻度线的长度
  89. ),
  90. paper_bgcolor='white', # 设置纸张背景颜色为白色
  91. plot_bgcolor='white', # 设置图表背景颜色为白色
  92. margin=dict(t=50, b=10) # t为顶部(top)间距,b为底部(bottom)间距
  93. )
  94. # 保存图像
  95. output_file = os.path.join(outputAnalysisDir, f"{name}.png")
  96. fig.write_image(output_file, scale=2)