如何利用matplotlib hist2d实现磁矢量加权的二维直方图?
解决方案
要实现先对每个直方图箱(像素)内的磁场矢量分量求和,再计算总磁场模的二维直方图,直接用hist2d的weights参数无法完成(它仅支持一维权重数组)。我们可以手动分箱并对磁场分量分别求和,步骤如下:
步骤说明
- 确定直方图的分箱边缘,确保和你原本的
hist2d分箱逻辑一致; - 为每个粒子分配对应的箱索引;
- 对每个箱内的磁场x/y/z分量分别求和,得到该箱的总磁场矢量;
- 计算总磁场矢量的模,最后绘制二维直方图。
代码示例
import numpy as np import matplotlib.pyplot as plt # 替换为你的实际数据 x = np.random.randn(10000) # 示例x坐标 y = np.random.randn(10000) # 示例y坐标 # 示例磁场矢量:包含方向相反的测试用例 mag = np.random.randn(10000, 3) mag[0] = [1, 0, 0] mag[1] = [-1, 0, 0] x[0], x[1] = 0, 0 y[0], y[1] = 0, 0 # 1. 设置分箱数,可按需调整 bins = 50 # 获取x、y轴的分箱边缘(和hist2d默认逻辑一致) x_edges = np.linspace(x.min(), x.max(), bins + 1) y_edges = np.linspace(y.min(), y.max(), bins + 1) # 2. 获取每个粒子所在的箱索引(索引从0开始) x_idx = np.digitize(x, x_edges) - 1 y_idx = np.digitize(y, y_edges) - 1 # 将二维箱索引转为一维线性索引,方便按箱求和 linear_idx = y_idx * bins + x_idx # 3. 对磁场的三个分量分别按箱求和 mag_x_sum = np.bincount(linear_idx, weights=mag[:, 0], minlength=bins*bins).reshape(bins, bins) mag_y_sum = np.bincount(linear_idx, weights=mag[:, 1], minlength=bins*bins).reshape(bins, bins) mag_z_sum = np.bincount(linear_idx, weights=mag[:, 2], minlength=bins*bins).reshape(bins, bins) # 4. 计算每个箱的总磁场强度(模) total_mag_norm = np.sqrt(mag_x_sum**2 + mag_y_sum**2 + mag_z_sum**2) # 绘制二维直方图 fig, ax = plt.subplots(figsize=(8, 6)) # 使用pcolormesh绘制,注意转置数组以匹配坐标维度 im = ax.pcolormesh(x_edges, y_edges, total_mag_norm.T, shading='auto', cmap='viridis') plt.colorbar(im, label='总磁场强度') ax.set_xlabel('X 坐标') ax.set_ylabel('Y 坐标') ax.set_title('按总磁场强度加权的二维直方图') plt.show()
关键说明
- 该方法会正确处理磁场方向抵消的情况:比如同一箱内两个方向相反的磁场矢量,分量求和后相互抵消,总磁场模为0,符合物理实际;
- 如果需要和原本
hist2d的分箱完全一致,可以用np.histogram2d先获取分箱边缘:
再复用上述逻辑计算分量和。counts, x_edges, y_edges = np.histogram2d(x, y, bins=bins)
内容的提问来源于stack exchange,提问作者Martin Phar AC Fournier
相关产品推荐
相关产品推荐

