使用plt.hist2d等工具生成二维分布异常的修复咨询
问题描述
我需要基于A_beams和B_beams构建二维分布,先后使用plt.hist2d、np.histogram2d及scipy.stats.binned_statistic_2d工具,但生成的分布均不符合预期。已知数据中A_beams数值始终大于或等于B_beams,但imshow展示的分布云却位于A=B直线下方,数据本身无问题,请问该如何修复?
数据示例:A_beams=[3,6,9,12,4...],B_beams=[2,4,5,9,2...]
使用的代码片段:
matrix=scipy.stats.binned_statistic_2d(a_beams, b_beams,None,'count',bins=50) ax1 = fig.add_subplot(151) im1 = ax1.imshow(matrix, interpolation=None,norm=mpl.colors.LogNorm(), cmap=plt.cm.RdYlBu_r)
修复方案
问题核心在于imshow的坐标轴逻辑与二维统计结果的维度对应不匹配,加上对scipy.stats.binned_statistic_2d返回值的错误处理,具体修复步骤如下:
- 正确提取统计矩阵
scipy.stats.binned_statistic_2d返回的是一个结果对象,而非直接的计数矩阵,需要提取其statistic属性:
import scipy.stats import matplotlib.pyplot as plt import matplotlib as mpl # 正确获取统计结果 result = scipy.stats.binned_statistic_2d(a_beams, b_beams, None, 'count', bins=50) matrix = result.statistic
- 修正imshow的维度与坐标轴方向
imshow默认将矩阵第一行绘制在图像顶部,且默认维度顺序与统计结果的(A分箱, B分箱)不匹配,导致分布显示反转。解决方式有两种:
- 方案一:转置矩阵+设置origin参数
转置矩阵让维度对应正确,同时设置origin='lower'让坐标轴从左下角开始,匹配常规数据分布的展示逻辑:
ax1 = fig.add_subplot(151) im1 = ax1.imshow(matrix.T, interpolation=None, norm=mpl.colors.LogNorm(), cmap=plt.cm.RdYlBu_r, origin='lower') # 设置轴标签与刻度范围 x_edges = result.x_edge y_edges = result.y_edge ax1.set_xlabel('A_beams') ax1.set_ylabel('B_beams') ax1.set_xlim(0, len(x_edges)-1) ax1.set_ylim(0, len(y_edges)-1) # 可选:用实际数据值作为刻度标签 # ax1.set_xticks(range(len(x_edges))[::5]) # ax1.set_xticklabels([f"{x:.1f}" for x in x_edges][::5]) # ax1.set_yticks(range(len(y_edges))[::5]) # ax1.set_yticklabels([f"{y:.1f}" for y in y_edges][::5])
- 方案二:改用pcolormesh(更推荐)
pcolormesh直接基于分箱边缘绘制,天生适配二维统计结果的维度与坐标轴逻辑,无需额外调整:
ax1 = fig.add_subplot(151) ax1.pcolormesh(result.x_edge, result.y_edge, matrix.T, norm=mpl.colors.LogNorm(), cmap=plt.cm.RdYlBu_r) ax1.set_xlabel('A_beams') ax1.set_ylabel('B_beams')
- 添加参考线验证
绘制A=B的参考线,确认分布位于线上方:
min_val = min(min(a_beams), min(b_beams)) max_val = max(max(a_beams), max(b_beams)) ax1.plot([min_val, max_val], [min_val, max_val], 'k--', label='A=B') ax1.legend()
内容的提问来源于stack exchange,提问作者dkagramanyan
相关产品推荐
相关产品推荐

