访问 N 维直方图的前两个维度
Access first two dimensions of N dimenional histogram
我通过 numpy
的 histogramdd 生成一个 N 维直方图,维度在 2-5 之间变化。我需要绘制其前两个维度的二维直方图,即:
当只有两个维度时,我可以很容易地做到这一点,如下所示。我如何将此代码概括为 N 维,以便它始终绘制前两个?
import numpy as np
import matplotlib.pyplot as plt
dims = np.random.randint(2, 5)
print('Dimensions: {}'.format(dims))
N_pts = np.random.randint(100, 500)
print('Points: {}'.format(N_pts))
A_pts, bin_edges = [], []
for _ in range(dims):
d_min, d_max = np.random.uniform(-1., 1.), np.random.uniform(-1., 1.)
sample = np.random.uniform(d_min, d_max, N_pts)
A_pts.append(sample)
# Define bin edges separately, since they come from somewhere else.
bin_edges.append(np.histogram(sample, bins='auto')[1])
# Obtain N-dimensional histogram
A_h = np.histogramdd(A_pts, bins=bin_edges)[0]
print(np.shape(A_h))
# Subplots.
fig = plt.figure()
ax0 = fig.add_subplot(1, 2, 1)
ax1 = fig.add_subplot(1, 2, 2)
# 2D histogram x,y ranges
x_extend = [min(A_pts[0]), max(A_pts[0])]
y_extend = [min(A_pts[1]), max(A_pts[1])]
# Scatter plot for A.
ax0.invert_yaxis()
ax0.set_xlim(x_extend)
ax0.set_ylim(y_extend)
ax0.scatter(A_pts[0], A_pts[1], c='b', label='A')
for x_ed in bin_edges[0]:
# vertical lines
ax0.axvline(x_ed, linestyle=':', color='k', zorder=1)
for y_ed in bin_edges[1]:
# horizontal lines
ax0.axhline(y_ed, linestyle=':', color='k', zorder=1)
# 2D histogram.
# Grid for pcolormesh, using first two dimensions
X, Y = np.meshgrid(bin_edges[0], bin_edges[1])
HA = np.rot90(A_h)
HA = np.flipud(HA)
ax1.pcolormesh(X, Y, HA, cmap=plt.cm.Blues)
# Manipulate axis and ranges.
ax1.invert_yaxis()
ax1.set_xlim(x_extend)
ax1.set_ylim(y_extend)
fig.subplots_adjust(hspace=1)
plt.show()
您必须首先确定 "the first two dimensions of the histogram" 的确切含义。为了直观地想象您要从示例中的二维开始,并希望将其减少到第一维。
你可以看到有两种明显的可能性。
- 选择一列或
- 对各行求和得到一个汇总列
当然,摘要解决方案只为您提供原始数据的一维直方图。
所以对于你的代码。
如果要对剩余维度进行分箱:
A_2d = A_h.reshape(A_h.shape[:2] + (-1,)).sum(axis=-1)
如果要切片:
A_2d = A_h.reshape(A_h.shape[:2] + (-1,))[..., 0]
reshape 将前两个维度分开并分解所有其他维度((-1,) 指示 reshape 将所有剩余的内容放入相应的轴中)生成的数组将混合轴作为其最后一个维度。第一行沿着这个轴求和,第二行只选择一个切片。如果你愿意,你可以选择其他的(将 0 更改为其他整数)。
我通过 numpy
的 histogramdd 生成一个 N 维直方图,维度在 2-5 之间变化。我需要绘制其前两个维度的二维直方图,即:
当只有两个维度时,我可以很容易地做到这一点,如下所示。我如何将此代码概括为 N 维,以便它始终绘制前两个?
import numpy as np
import matplotlib.pyplot as plt
dims = np.random.randint(2, 5)
print('Dimensions: {}'.format(dims))
N_pts = np.random.randint(100, 500)
print('Points: {}'.format(N_pts))
A_pts, bin_edges = [], []
for _ in range(dims):
d_min, d_max = np.random.uniform(-1., 1.), np.random.uniform(-1., 1.)
sample = np.random.uniform(d_min, d_max, N_pts)
A_pts.append(sample)
# Define bin edges separately, since they come from somewhere else.
bin_edges.append(np.histogram(sample, bins='auto')[1])
# Obtain N-dimensional histogram
A_h = np.histogramdd(A_pts, bins=bin_edges)[0]
print(np.shape(A_h))
# Subplots.
fig = plt.figure()
ax0 = fig.add_subplot(1, 2, 1)
ax1 = fig.add_subplot(1, 2, 2)
# 2D histogram x,y ranges
x_extend = [min(A_pts[0]), max(A_pts[0])]
y_extend = [min(A_pts[1]), max(A_pts[1])]
# Scatter plot for A.
ax0.invert_yaxis()
ax0.set_xlim(x_extend)
ax0.set_ylim(y_extend)
ax0.scatter(A_pts[0], A_pts[1], c='b', label='A')
for x_ed in bin_edges[0]:
# vertical lines
ax0.axvline(x_ed, linestyle=':', color='k', zorder=1)
for y_ed in bin_edges[1]:
# horizontal lines
ax0.axhline(y_ed, linestyle=':', color='k', zorder=1)
# 2D histogram.
# Grid for pcolormesh, using first two dimensions
X, Y = np.meshgrid(bin_edges[0], bin_edges[1])
HA = np.rot90(A_h)
HA = np.flipud(HA)
ax1.pcolormesh(X, Y, HA, cmap=plt.cm.Blues)
# Manipulate axis and ranges.
ax1.invert_yaxis()
ax1.set_xlim(x_extend)
ax1.set_ylim(y_extend)
fig.subplots_adjust(hspace=1)
plt.show()
您必须首先确定 "the first two dimensions of the histogram" 的确切含义。为了直观地想象您要从示例中的二维开始,并希望将其减少到第一维。
你可以看到有两种明显的可能性。
- 选择一列或
- 对各行求和得到一个汇总列
当然,摘要解决方案只为您提供原始数据的一维直方图。
所以对于你的代码。
如果要对剩余维度进行分箱:
A_2d = A_h.reshape(A_h.shape[:2] + (-1,)).sum(axis=-1)
如果要切片:
A_2d = A_h.reshape(A_h.shape[:2] + (-1,))[..., 0]
reshape 将前两个维度分开并分解所有其他维度((-1,) 指示 reshape 将所有剩余的内容放入相应的轴中)生成的数组将混合轴作为其最后一个维度。第一行沿着这个轴求和,第二行只选择一个切片。如果你愿意,你可以选择其他的(将 0 更改为其他整数)。