4

假设我想建立在某个 bin 范围 nbin 上平滑的粒子数据直方图。现在我有 5 个具有不同质量粒子的数据集(每组 x,y 具有不同的质量)。通常,粒子位置的直方图是一个简单的情况(使用 numpy):

heatmap, xedges, yedges = np.histogram2d(x, y, bins=nbin)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
heatmap = np.flipud(np.rot90(heatmap))
ax.imshow(heatmap, extent=extent)

但是,如果我想添加下一批粒子,它们具有不同的质量,因此密度会有所不同。有没有办法通过某个常数对直方图进行加权,这样绘制的热图将是密度的真实表示,而不仅仅是粒子总数的分箱?

我知道“权重”是一个特征,但它是否只是设置 weights = m_i 的情况,其中 m_i 是每个数据集 1-5 的粒子质量?

4

1 回答 1

4

该参数需要一个与和weights长度相同的数组。. 它不会广播一个常数值,所以即使每次调用的质量相同,你仍然必须使用类似的东西xynp.histogram2dnp.histogram2d

weights=np.ones_like(x)*mass

现在,如果使用,您可能会遇到的一个问题bin=nbin是 bin 边缘 ,xedges可能yedges会根据您传递给的x和的值而改变。如果您天真地将热图添加在一起,最终结果将在错误的位置累积粒子密度。ynp.histogram2d

因此,如果您想np.histogram2d多次调用并将部分热图添加在一起,则必须提前确定您想要 bin 边缘的位置。

例如:

import numpy as np
import itertools as IT
import matplotlib.pyplot as plt
N = 50
nbin = 10

xs = [np.array([i,i,i+1,i+1]) for i in range(N)]
ys = [np.array([i,i+1,i,i+1]) for i in range(N)]
masses = np.arange(N)

heatmap = 0
xedges = np.linspace(0, N, nbin)
yedges = np.linspace(0, N, nbin)

for x, y, mass in IT.izip(xs, ys, masses):
    hist, xedges, yedges = np.histogram2d(
        x, y, bins=[xedges, yedges], weights=np.ones_like(x)*mass)
    heatmap += hist

extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
heatmap = np.flipud(np.rot90(heatmap))
fig, ax = plt.subplots()
ax.imshow(heatmap, extent=extent, interpolation='nearest')
plt.show()

产量

在此处输入图像描述

于 2013-06-21T18:28:36.590 回答