Python绘制带拐点垂直线的冷负荷持续曲线异常排查
Python冷负荷持续曲线绘制问题:垂直虚线异常与拐点识别修复
问题概述
基于Excel冷负荷(Kältelast)数据绘制负荷持续曲线,要求X轴分别为时间占比和累计时长,并在拐点切线交点处添加垂直虚线。当前代码运行后,axvline未生成预期的垂直红线,反而显示水平线,核心问题出在拐点识别逻辑错误,导致传入axvline的X坐标无效。
数据样例
Excel数据结构示例(两列):
时间序号,冷负荷(KW) 0,122.5 1,120.3 2,118.7 ... 8759,78.2
当前代码(存在问题版本)
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 读取Excel数据 df = pd.read_excel('冷负荷数据.xlsx') # 降序排序冷负荷(负荷持续曲线要求) load_data = df['冷负荷(KW)'].sort_values(ascending=False).values # 计算X轴参数 time_ratio = np.linspace(0, 1, len(load_data)) # 时间占比0-1 cumulative_hours = np.linspace(0, 8760, len(load_data)) # 累计时长0-8760h # 拐点识别(逻辑存在缺陷) def find_inflection(load): second_deriv = np.diff(np.diff(load)) inflect_idx = np.where(np.sign(second_deriv[:-1]) != np.sign(second_deriv[1:]))[0][0] + 2 return inflect_idx inflect_idx = find_inflection(load_data) inflect_ratio = time_ratio[inflect_idx] inflect_cum = cumulative_hours[inflect_idx] # 绘图 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6)) # 子图1:时间占比为X轴 ax1.plot(time_ratio, load_data, 'b-', linewidth=1) # 此处预期垂直红线,实际显示水平线 ax1.axvline(x=inflect_ratio, color='r', linestyle='--') ax1.set_xlabel('时间占比') ax1.set_ylabel('冷负荷(KW)') ax1.set_title('负荷持续曲线(时间占比)') # 子图2:累计时长为X轴 ax2.plot(cumulative_hours, load_data, 'b-', linewidth=1) ax2.axvline(x=inflect_cum, color='r', linestyle='--') ax2.set_xlabel('累计时长(h)') ax2.set_ylabel('冷负荷(KW)') ax2.set_title('负荷持续曲线(累计时长)') plt.tight_layout() plt.show()
效果对比
- 当前效果图:
(显示水平线而非垂直虚线) - 目标效果图:
(在切线交点处显示垂直虚线)
问题修复方案
1. 水平线问题根源
如果axvline显示为水平线,大概率是拐点X坐标计算错误:要么是误将Y轴负荷值当作X坐标传入,要么是拐点识别逻辑输出了无效的索引,导致time_ratio[inflect_idx]或cumulative_hours[inflect_idx]取值异常。
2. 拐点识别逻辑修正(切线交点法)
负荷持续曲线的拐点应为高负荷段与低负荷段切线的交点,替换原二阶导数识别法,改用直线拟合求交点:
def get_tangent_intersection(x_axis, load_values): # 划分高负荷段(前20%)和低负荷段(后20%),可根据数据调整比例 high_split = int(len(x_axis) * 0.2) low_split = int(len(x_axis) * 0.8) # 拟合高负荷段直线 high_coeff = np.polyfit(x_axis[:high_split], load_values[:high_split], 1) high_line = np.poly1d(high_coeff) # 拟合低负荷段直线 low_coeff = np.polyfit(x_axis[low_split:], load_values[low_split:], 1) low_line = np.poly1d(low_coeff) # 计算两条直线的X交点 intersect_x = (low_line[0] - high_line[0]) / (high_line[1] - low_line[1]) return intersect_x # 计算两个X轴对应的交点坐标 intersect_ratio = get_tangent_intersection(time_ratio, load_data) intersect_cum = get_tangent_intersection(cumulative_hours, load_data)
3. 修正绘图代码
将axvline的X参数替换为正确的交点坐标:
# 子图1修正 ax1.axvline(x=intersect_ratio, color='r', linestyle='--', linewidth=1.5) # 子图2修正 ax2.axvline(x=intersect_cum, color='r', linestyle='--', linewidth=1.5)
4. 额外验证步骤
- 确认冷负荷数据已严格降序排列,这是负荷持续曲线的绘制基础,若数据未排序,曲线形态会错误,导致拐点识别失效。
- 打印
intersect_ratio和intersect_cum的值,验证是否在X轴合理范围内(时间占比0-1,累计时长0-8760)。
内容的提问来源于stack exchange,提问作者random_bot
相关产品推荐
相关产品推荐

