You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Matplotlib连接含缺失值的无关数据点绘制曲线

问题描述

我有某区域单日逐小时温度的多月度数据集,因硬件故障存在数据缺失,缺失时长从几小时到连续数小时不等。已用NaN值标记缺失数据,补全了单日内部的缺失时段,但未处理连续多日的缺失。需要绘制整月温度随时间变化的曲线,要求仅显示非空数据,避免Matplotlib连接无关数据点。

但在2023年10月的数据绘图时出现异常:2023/10/09左右的缺失数据被错误连接,而2023/10/21至2023/10/29的大量缺失数据却未被连接。尝试按天拆分绘制来避免连接问题,但导致图例数量与天数一致,不符合需求。当前生成异常结果的代码如下:

"""
创建并展示指定月份的温度分布曲线。

参数:
month_year_data (pandas.DataFrame): 包含该月份逐小时温度数据的DataFrame。
month_name (str): 用于图表标注的月份名称。
year (int): 用于图表标注的年份。

返回:
None
"""
# 创建单个图表
fig, ax = plt.subplots(figsize=(20, 10))

# 绘制各区域的温度分布
zones = ['远区', '中区', '近区']
colors = ['blue', 'green', 'red', 'black']  # 定义各区域颜色
for i, zone in enumerate(zones):
    ax.plot(month_year_data.index, month_year_data[zone], label=zone, color=colors[i], linestyle='-')

# 设置坐标轴标签
ax.set_xlabel('时间')
ax.set_ylabel('温度 (°C)')
# 设置图表标题
ax.set_title(f'{month_name}-{year}逐小时温度变化曲线')
# 旋转x轴标签以提升可读性
plt.xticks(rotation=45)
# 添加图例
ax.legend()
解决方案

核心思路

将每个区域的温度数据拆分为连续非NaN的子序列,分别绘制这些子序列,确保跨缺失段的无关数据点不会被连接;同时仅在首次绘制区域数据时添加图例标签,避免图例重复。

修改后的代码

"""
创建并展示指定月份的温度分布曲线。

参数:
month_year_data (pandas.DataFrame): 包含该月份逐小时温度数据的DataFrame(索引为datetime类型)。
month_name (str): 用于图表标注的月份名称。
year (int): 用于图表标注的年份。

返回:
None
"""
import matplotlib.pyplot as plt
import pandas as pd

# 创建单个图表
fig, ax = plt.subplots(figsize=(20, 10))

# 定义各区域及对应颜色
zones = ['远区', '中区', '近区']
colors = ['blue', 'green', 'red', 'black']

for i, zone in enumerate(zones):
    # 获取当前区域非NaN的温度数据
    temp_series = month_year_data[zone].dropna()
    if temp_series.empty:
        continue  # 跳过无有效数据的区域
    
    # 识别连续数据段的分界点:相邻时间间隔不为1小时则为分界
    time_diff = temp_series.index.to_series().diff()
    breaks = time_diff != pd.Timedelta(hours=1)
    # 按分界点分组,得到多个连续数据子序列
    data_groups = temp_series.groupby(breaks.cumsum())
    
    # 绘制每个连续数据段,仅第一个段添加图例标签
    first_segment = True
    for _, segment in data_groups:
        if first_segment:
            ax.plot(segment.index, segment.values, label=zone, color=colors[i], linestyle='-')
            first_segment = False
        else:
            ax.plot(segment.index, segment.values, color=colors[i], linestyle='-')

# 设置图表元素
ax.set_xlabel('时间')
ax.set_ylabel('温度 (°C)')
ax.set_title(f'{year}年{month_name}逐小时温度变化曲线')
plt.xticks(rotation=45)
ax.legend()
plt.show()

代码说明

  1. 数据拆分:通过判断相邻时间索引的间隔是否为1小时(符合逐小时数据的特性),将非NaN数据拆分为多个连续子序列,确保每个子序列内部无缺失。
  2. 图例控制:仅在绘制区域的第一个连续子序列时添加label参数,后续子序列不添加,避免图例中出现重复条目。
  3. 空数据处理:添加了空数据判断,避免无有效数据的区域引发绘图错误。

内容的提问来源于stack exchange,提问作者fidjii 32

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:05:29