查找2D直方图的峰值
查找2D直方图的峰值
我制作了一张二维直方图,其中包含一些(x, y)的数据,得到的图像如下所示:\n\n我想找到存储在H中最大值的点的(x, y)坐标。例如,在上面的图像中,最大值的大致坐标将是两个点:(1090, 1040)和(1110, 1090)。\n这是我的代码:\n
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 # 代码所在目录的路径。 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()
\n
\n编辑\n我尝试了Marek和qarma发布的解决方案,试图获取存储最大值的箱子的坐标,而不是它们的索引,如下所示:\n
# Marek的答案 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的答案 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('\nqarma') 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]])
\n结果如下所示:\n
Marek (53, 50) (1072.7838144329899, 1005.0837113402063) qarma (53, 50) (1072.7838144329899, 1005.0837113402063) (1072.7838144329899, 1005.0837113402063, 1092.8257731958763, 1065.3611340206187)
\n所以最大坐标是相同的,这是好的!但是我有一个小问题,因为如果我放大二维图,我会发现无论是全局最大值还是局部最大值的坐标都有一点偏离中心:\n\n为什么会这样?
在这段内容中,提到了如何找到二维直方图的峰值。但是作者提到,找到所有峰值的坐标是留给读者的练习。然后,作者展示了如何通过numpy中的argwhere函数找到直方图中的峰值坐标。接着,作者编辑了代码,并解释了为什么在计算中心位置时使用了"x + 2"而不是"x + 1"。作者解释说,由于边界数组比直方图数组在对应维度上大一个元素,所以使用"x + 2"。并且通过例子"len(foo[1:1+2]) == 2"来说明了这个原因。
通过整理上述内容,可得以下文章:
找到二维直方图的峰值
在数据分析和图像处理中,经常需要找到二维直方图中的峰值以进行进一步的分析和处理。下面介绍了一种方法来找到二维直方图的全局最大值,并展示了如何找到所有峰值的坐标。
首先,可以通过以下代码找到二维直方图的全局最大值的坐标:
idx = list(H.flatten()).index(H.max()) x, y = idx / H.shape[1], idx % H.shape[1]
这段代码将二维直方图H展平为一维数组,并找到最大值的索引。然后,通过除法和取余运算,将索引转换为对应的x和y坐标。
然而,作者并未提供找到所有峰值的坐标的方法。但是,可以使用numpy库中的argwhere函数来实现。以下是使用argwhere函数找到二维直方图中所有峰值的坐标的代码:
numpy.argwhere(H == H.max())
这段代码将返回一个包含所有满足条件的峰值坐标的数组。
在编辑代码的过程中,作者对代码进行了修改,并解释了为什么在计算中心位置时使用了"x + 2"而不是"x + 1"。原因是边界数组比直方图数组在对应维度上大一个元素。以下是修改后的代码示例:
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])
这段代码通过遍历所有满足条件的峰值坐标,并使用x和y坐标来计算中心位置。在计算中心位置时,使用了"x + 2"来获取x边界的范围。这是因为边界数组比直方图数组在对应维度上大一个元素。
通过上述代码示例和解释,我们可以找到二维直方图的峰值,并且可以找到所有峰值的坐标。同时,我们也了解了在计算中心位置时为什么使用了"x + 2"而不是"x + 1"的原因。这些方法和技巧在数据分析和图像处理中具有重要的应用价值。
在解决问题之前,让我们先了解一下问题的背景和出现的原因。问题是要找到二维直方图的峰值。下面的代码片段展示了如何使用Python库findpeaks来解决这个问题。
首先,我们需要安装findpeaks库。可以使用以下命令进行安装:pip install findpeaks
。
接下来,我们引入findpeaks库:from findpeaks import findpeaks
。
然后,我们导入一个二维示例数据集:img = fp.import_example()
。
然后,我们使用findpeaks库中的fit函数来进行拟合:fp.fit(img)
。
完成拟合后,我们可以使用plot函数来绘制二维直方图:fp.plot()
。
在绘制的图中,可以看到点1、2和3显示了最强的峰值,其余部分则较弱。
我们还可以使用persistence函数来计算峰值的持续性:fp.plot_persistence()
。
在持续性图中,可以看到点1、2和3的持续性最高,其余部分则较低。
通过使用findpeaks库,我们可以方便地找到二维直方图中的峰值,并通过持续性图来评估峰值的重要性。
以上就是解决问题的方法和代码示例。希望对你有所帮助!