如何用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
相关产品推荐
相关产品推荐

