关于python:找到2d直方图的峰值

Find peak of 2d histogram

我对一些(x, y)数据做了二维直方图,得到了这样一幅图像:

histogram-2d

我想要一种方法来获取存储H中最大值的点的(x, y)坐标。例如,对于上面的图像,它将是两个具有近似坐标的点:(1090, 1040)(1110, 1090)

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from os import getcwd
from os.path import join, realpath, dirname

# Path to dir where this code exists.
mypath = realpath(join(getcwd(), dirname(__file__)))
myfile = 'datafile.dat'

x, y = np.loadtxt(join(mypath,myfile), usecols=(1, 2), unpack=True)

fig = plt.figure()
ax = fig.add_subplot(111)

xmin, xmax = min(x), max(x)
ymin, ymax = min(y), max(y)

rang = [[xmin, xmax], [ymin, ymax]]

binsxy = [int((xmax - xmin) / 20), int((ymax - ymin) / 20)]

H, xedges, yedges = np.histogram2d(x, y, range=rang, bins=binsxy)

extent = [yedges[0], yedges[-1], xedges[0], xedges[-1]]
cp = ax.imshow(H.transpose()[::-1], interpolation='nearest', extent=extent, cmap=cm.jet)
fig.colorbar(cp)

plt.show()

编辑

我尝试过Marek和Qarma发布的解决方案,试图获得垃圾箱的坐标,而不是它们的索引,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Marek's answer
x_cent, y_cent = unravel_index(H.argmax(), H.shape)
print('Marek')
print(x_cent, y_cent)
print(xedges[x_cent], yedges[y_cent])

# qarma's answer
idx = list(H.flatten()).index(H.max())
x_cent2, y_cent2 = idx / H.shape[1], idx % H.shape[1]
local_maxs = np.argwhere(H == H.max())
print('
qarma'
)
print(x_cent2, y_cent2)
print(xedges[x_cent2], yedges[y_cent2])
print(xedges[local_maxs[0,0]], yedges[local_maxs[0,1]], xedges[local_maxs[1,0]], yedges[local_maxs[1,1]])

结果是:

1
2
3
4
5
6
7
8
Marek
(53, 50)
(1072.7838144329899, 1005.0837113402063)

qarma
(53, 50)
(1072.7838144329899, 1005.0837113402063)
(1072.7838144329899, 1005.0837113402063, 1092.8257731958763, 1065.3611340206187)

所以最大坐标是相同的,这是好的!现在我有一个小问题,因为如果放大二维图,我会发现坐标在全局最大值和局部最大值上都有点偏离中心:

氧化镁

这是为什么?


下面是如何找到第一个全局最大值

1
2
idx = list(H.flatten()).index(H.max())
x, y = idx / H.shape[1], idx % H.shape[1]

找到所有最大值的坐标留给读者作为练习…

1
numpy.argwhere(H == H.max())

编辑

您的代码:

1
H, xedges, yedges = np.histogram2d(x, y, range=rang, bins=binsxy)

这里,H包含柱状图值和柱状图箱的xedges, yedges边界。注意,edges数组的大小比对应维度中H数组的大小大一倍。因此:

1
2
3
for x, y in numpy.argwhere(H == H.max()):
    # center is between x and x+1
    print numpy.average(xedges[x:x + 2]), numpy.average(yedges[y:y + 2])


这个问题应该对您有所帮助:python:获取numpy数组中最大项的位置

你可以用H.max()得到最大值,然后与H比较,用numpy.nonzero找到所有最大值的位置:numpy.nonzero(H.max() == H)。这将比H.argmax()更昂贵,但您将获得所有最大值。