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

如何在X-Y平面划分网格(Bin)并基于Z值统计量绘制热力图

嘿,我来帮你搞定这些问题!针对你提出的三个核心需求,我整理了一套清晰的实现方案,用scipy.stats.binned_statistic_2d来简化分箱统计,同时解决坐标轴固定和空分箱的问题:

1. 标准实现方案:分箱统计+热力图绘制

scipy.stats.binned_statistic_2d是处理这类2D分箱统计的利器,它直接支持mean、std(标准差)、var(方差)等多种统计量,不用手动计算权重和计数的比值,省心很多。下面是完整的可运行代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import binned_statistic_2d

# 你的原始数据
x = np.array([10,2,-4,12,3,6,8,14])
y = np.array([5,5,-6,8,20,10,2,2])
z = np.array([4,6,10,40,22,14,-20,8])

# 设置分箱:覆盖x和y的[-20,20]范围,这里设为5个分点(4个分箱),可按需调整num值
num_bins = 5
x_bins = np.linspace(-20, 20, num=num_bins)
y_bins = np.linspace(-20, 20, num=num_bins)

# 计算分箱内的均值和标准差(方差的话把statistic改成'var'即可)
mean_stats = binned_statistic_2d(x, y, z, statistic='mean', bins=[x_bins, y_bins])
std_stats = binned_statistic_2d(x, y, z, statistic='std', bins=[x_bins, y_bins])

# 处理空分箱:将样本数为0的分箱统计值设为NaN
mean_vals = mean_stats.statistic
mean_vals[mean_stats.count == 0] = np.nan

std_vals = std_stats.statistic
std_vals[std_stats.count == 0] = np.nan

# 绘制两幅热力图:均值和标准差
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# 均值热力图
im1 = ax1.imshow(mean_vals.T, origin='lower', cmap='RdBu', 
                 extent=[x_bins[0], x_bins[-1], y_bins[0], y_bins[-1]])
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_title('Mean of Z per Bin')
fig.colorbar(im1, ax=ax1, label='Mean Z')

# 标准差热力图
im2 = ax2.imshow(std_vals.T, origin='lower', cmap='RdBu', 
                 extent=[x_bins[0], x_bins[-1], y_bins[0], y_bins[-1]])
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_title('Standard Deviation of Z per Bin')
fig.colorbar(im2, ax=ax2, label='Std Z')

# 固定坐标轴范围
ax1.set_xlim(-20, 20)
ax1.set_ylim(-20, 20)
ax2.set_xlim(-20, 20)
ax2.set_ylim(-20, 20)

plt.tight_layout()
plt.show()

2. 固定坐标轴范围的关键

我在代码里用了两种方式确保坐标轴固定在[-20,20]:

  • 首先,分箱的边界x_bins和y_bins直接用np.linspace(-20,20,...)生成,覆盖目标范围;
  • 然后,imshow的extent参数明确指定了热力图的x/y轴范围,再配合set_xlim和set_ylim双重保障,完全避免了matplotlib自动缩放坐标轴的问题。

3. 空分箱设为NaN的解决方法

binned_statistic_2d返回的统计对象里有个count属性,记录了每个分箱内的样本数量。我们只需要找到count == 0的位置,把对应的统计值设为np.nan即可:

# 以标准差为例
std_vals = std_stats.statistic
std_vals[std_stats.count == 0] = np.nan

这样绘图的时候,空分箱就不会显示成错误的0值,而是自动呈现为空白(或者根据colormap的设置处理)。

如果需要计算方差,只需要把statistic='std'改成statistic='var'就行,其他逻辑完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:07:49