如何数值计算散点质量分布的质量图与质量密度图
解答
你当前生成的图不能直接表示总质量分布。
你写的myplot函数本质是先通过二维直方图统计每个网格内的散点数量,再做高斯平滑得到点的数密度估计,输出数值的物理意义是对应位置附近的散点数量期望值,本身和质量量纲无关,再加高斯平滑会把单个网格的数值扩散到周边,没有做守恒校正的话数值总量也会变,色条数值远小于50kg是完全正常的。
下面是你要的质量图、质量密度图的实现方法:
总质量分布图(质量图)
总质量图的每个网格值代表对应网格范围内的总质量。如果所有散点质量固定为50kg,直接把二维直方图统计得到的点计数乘以单质点质量即可得到离散的质量分布;如果需要做高斯平滑让视觉效果更连续,必须加一步质量守恒校正,避免平滑过程中总质量出现偏差。
对应实现代码:
import numpy as np from scipy.ndimage import gaussian_filter def get_mass_map(x, y, point_mass, sigma=20, bins=1000): # 统计每个网格的散点计数 count, xedges, yedges = np.histogram2d(x, y, bins=bins) # 计算每个网格的原始总质量 mass_map_raw = count * point_mass # 高斯平滑 mass_map_smooth = gaussian_filter(mass_map_raw, sigma=sigma) # 质量守恒校正:按总质量比例缩放,保证平滑前后全图总质量一致 mass_map_smooth = mass_map_smooth * (mass_map_raw.sum() / mass_map_smooth.sum()) extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]] return mass_map_smooth.T, extent
这一步输出的质量图单位为kg,色条量级会和质量匹配。
质量密度图
质量密度的物理意义是单位面积内的质量,计算逻辑是用每个网格的总质量除以单个网格的实际面积即可。如果需要平滑,同样要做守恒校正,保证密度在全图的积分结果等于所有散点的总质量,可以用这个规则校验结果是否正确。
对应实现代码:
def get_mass_density_map(x, y, point_mass, sigma=20, bins=1000): count, xedges, yedges = np.histogram2d(x, y, bins=bins) # 计算单个网格的尺寸和面积 dx = xedges[1] - xedges[0] dy = yedges[1] - yedges[0] bin_area = dx * dy # 计算原始质量密度 density_raw = (count * point_mass) / bin_area # 高斯平滑+守恒校正 density_smooth = gaussian_filter(density_raw, sigma=sigma) density_smooth = density_smooth * (density_raw.sum() / density_smooth.sum()) extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]] return density_smooth.T, extent
输出的密度图单位为kg/坐标单位²,如果你的x/y坐标单位是米,对应单位就是kg/㎡。
绘图注意事项
你原来的绘图代码有两个容易踩的坑:
- 调用
imshow时没有传入extent参数,坐标轴显示的是网格索引,不是你原始数据的实际坐标值 - 没有设置
origin='lower',会导致y轴方向和散点图上下翻转
正确的密度图/质量图绘图写法参考:
img = ax[1].imshow(plot_data, extent=extent, origin='lower') plt.colorbar(img, label='对应物理量单位')
内容的提问来源于stack exchange,提问作者Riemannator
相关产品推荐
相关产品推荐

