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

如何用Matplotlib为时间序列缺失值区域添加红色垂直高亮?

如何在Matplotlib时序图中高亮缺失数据区间?

我已导入matplotlib与pandas库,编写了如下plot_missing函数生成时间序列图表,但缺失日期区间的高亮未显示。请问如何在该Matplotlib时序图上绘制垂直矩形或高亮来标记缺失数据区域?

原代码如下:

def plot_missing(main):
    m_df = fill_missing_timestamps(main[['Date', 'Mean']], 'Mean')

    # Find missing 'Mean' values
    missing_values = m_df['Mean'].isna()

    # Create a mask for missing data
    mask = np.zeros_like(m_df['Mean'])
    mask[missing_values] = 1

    # Identify the start and end indices of missing data intervals
    start_indices = np.where(np.diff(mask) == 1)[0] + 1
    end_indices = np.where(np.diff(mask) == -1)[0]

    # Check if the first or last data point is missing
    if missing_values.iloc[0]:
        start_indices = np.insert(start_indices, 0, 0)
    if missing_values.iloc[-1]:
        end_indices = np.append(end_indices, len(main) - 1)

    # Create a separate column for the missing data intervals
    interval_column = np.zeros_like(m_df['Mean'])
    for start, end in zip(start_indices, end_indices):
        interval_column[start:end+1] = 1

    # Plot the time series with missing data in red and non-missing data in blue
    plt.plot(m_df['Date'], m_df['Mean'], color='pink', label='Non-Missing Data')
    plt.scatter(m_df['Date'][interval_column == 1], m_df['Mean'][interval_column == 1],
                color='red', label='Missing Data')

    # Set the title and labels
    plt.title('Raw Data \n Missing Data', fontweight='bold', fontsize=18)
    plt.xlabel('Date')
    plt.ylabel('Mean')
    plt.legend()

    plt.show()
    return

plot_missing(main)

解决方案

要高亮连续的缺失日期区间,核心是用Matplotlib的plt.axvspan()函数绘制垂直半透明矩形,替代原代码中用散点标记缺失值的逻辑。修改后的完整代码如下:

def plot_missing(main):
    m_df = fill_missing_timestamps(main[['Date', 'Mean']], 'Mean')

    # 标记缺失值
    missing_values = m_df['Mean'].isna()

    # 生成缺失值掩码,用于识别连续缺失区间
    mask = np.zeros_like(m_df['Mean'], dtype=int)
    mask[missing_values] = 1

    # 获取连续缺失区间的起止索引
    start_indices = np.where(np.diff(mask) == 1)[0] + 1
    end_indices = np.where(np.diff(mask) == -1)[0]

    # 处理首尾缺失的边界情况
    if missing_values.iloc[0]:
        start_indices = np.insert(start_indices, 0, 0)
    if missing_values.iloc[-1]:
        end_indices = np.append(end_indices, len(m_df) - 1)  # 修正原代码索引错误

    # 绘制时序曲线
    plt.plot(m_df['Date'], m_df['Mean'], color='pink', label='Non-Missing Data')

    # 循环绘制每个缺失区间的高亮矩形
    for start_idx, end_idx in zip(start_indices, end_indices):
        # 将索引转换为对应的日期
        start_date = m_df['Date'].iloc[start_idx]
        end_date = m_df['Date'].iloc[end_idx]
        # 绘制垂直高亮区间,alpha设置透明度避免遮挡曲线
        plt.axvspan(start_date, end_date, alpha=0.3, color='red')

    # 设置图表属性
    plt.title('Raw Data \n Missing Data', fontweight='bold', fontsize=18)
    plt.xlabel('Date')
    plt.ylabel('Mean')
    # 手动添加缺失区间的图例(axvspan不会自动加入图例)
    from matplotlib.patches import Patch
    legend_elements = [
        Patch(facecolor='pink', label='Non-Missing Data'),
        Patch(facecolor='red', alpha=0.3, label='Missing Intervals')
    ]
    plt.legend(handles=legend_elements)

    plt.show()
    return

plot_missing(main)

关键修改说明

  • 替换标记方式:用plt.axvspan()替代散点,直接绘制连续的垂直高亮区间,更直观展示缺失的日期范围。
  • 修正边界索引:原代码处理末尾缺失时误用len(main),改为len(m_df)(填充后的数据集长度),避免索引越界。
  • 自定义图例:通过Patch手动创建图例元素,解决axvspan无法自动生成图例的问题。
  • 透明度设置:alpha=0.3让高亮区域半透明,既突出缺失区间,又不会完全遮挡下方的时序曲线。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:27:50