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

Python中scipy.binned_statistic_2d生成热力图异常问题排查

问题排查:热力图在无数据区域异常绘制的原因及解决方法

核心原因分析

你的问题本质是分箱统计(binned)的范围覆盖了无数据区域,导致绘图函数对空分箱也进行了颜色渲染,而非仅聚焦真实数据点所在的区域。以下从代码参数、数据预处理两个维度排查:


1. 分箱参数设置不合理

如果使用matplotlib.hist2d、seaborn.histplot(带kind='hist2d')或plt.hexbin时,默认的分箱规则会基于整个坐标轴的范围生成 bins,哪怕该区域没有数据点。比如固定bins=30会强制把x/y轴全部分成30份,空分箱会被填充为0或NaN,但多数绘图函数默认会渲染这些空值区域。

解决方法:

  • 手动限定分箱范围为真实数据的取值区间,并设置仅渲染有数据的分箱:
    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    
    # 加载数据(替换为你的数据加载逻辑)
    df = pd.read_csv('cake_length_data.csv')
    
    # 获取数据的实际范围
    x_min, x_max = df['actual_deviation'].min(), df['actual_deviation'].max()
    y_min, y_max = df['target_deviation'].min(), df['target_deviation'].max()
    
    # 生成仅覆盖数据范围的分箱
    x_bins = np.linspace(x_min, x_max, num=25)  # 可调整num控制分箱数量
    y_bins = np.linspace(y_min, y_max, num=25)
    
    # 绘图时设置cmin=1,仅显示至少包含1个数据点的分箱
    plt.hist2d(df['actual_deviation'], df['target_deviation'], 
               bins=[x_bins, y_bins], cmin=1, cmap='viridis')
    # 叠加真实数据点
    plt.scatter(df['actual_deviation'], df['target_deviation'], color='red', s=10)
    plt.show()
    
  • 若使用六边形热力图(plt.hexbin),添加mincnt=1参数:
    plt.hexbin(df['actual_deviation'], df['target_deviation'], mincnt=1, cmap='viridis')
    

2. 数据存在异常值/极值

如果数据中包含超出正常范围的极值(比如录入错误的超大/超小偏差值),会导致分箱范围被强制拉宽,进而包含大量无数据的空白区域。

解决方法:

  • 先检查数据的统计特征,过滤异常值:
    # 查看数据分布统计
    print(df[['actual_deviation', 'target_deviation']].describe())
    
    # 过滤掉超出3σ范围的异常值(或根据业务规则调整)
    from scipy import stats
    df_clean = df[(np.abs(stats.zscore(df[['actual_deviation', 'target_deviation']])) < 3).all(axis=1)]
    
  • 用散点图确认数据的真实分布范围:
    df.plot.scatter(x='actual_deviation', y='target_deviation', color='red')
    

3. Seaborn Heatmap的网格矩阵未处理空值

如果是先通过pivot_table或histogram2d生成了全网格的统计矩阵,空分箱被填充为0而非NaN,Seaborn的heatmap会默认渲染0值区域。

解决方法:

  • 将空分箱的0值替换为NaN,并使用mask参数隐藏这些区域:
    import seaborn as sns
    
    # 生成分箱统计矩阵
    hist, xedges, yedges = np.histogram2d(df['actual_deviation'], df['target_deviation'], bins=[x_bins, y_bins])
    # 将0值替换为NaN
    hist[hist == 0] = np.nan
    
    # 绘制热力图时隐藏NaN区域
    sns.heatmap(hist, xticklabels=xedges.round(2), yticklabels=yedges.round(2), 
                mask=np.isnan(hist), cmap='viridis')
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:06:40