我正在尝试规范化从2dhistogram
派生的热图。无论数据点的数量多少,我都希望分布是相对的。
附加代码包含两组数据。一个人拥有比另一个更多的x,y坐标。虽然数字是随机的,但是可以对这些图进行标准化,因此密度表示分布而不是频率。使用下面的示例,由于样本量,x1-y1似乎会有更多变化。即使潜在的变化类似于x2-y2
import matplotlib.pyplot as plt
import random
import numpy as np
fig, ((ax1, ax2)) = plt.subplots(1,2)
x1 = [random.randrange(1,101,1) for _ in range (10000)]
y1 = [random.randrange(1,101,1) for _ in range (10000)]
x2 = [random.randrange(1,100,1) for _ in range (1000)]
y2 = [random.randrange(1,100,1) for _ in range (1000)]
zi, xi, yi = np.histogram2d(x1, y1, bins=40, normed = False)
im = ax1.imshow(zi, interpolation = 'gaussian', origin = 'lower', cmap = 'jet')
zi, xi, yi = np.histogram2d(x2, y2, bins=40, normed = False)
im = ax2.imshow(zi, interpolation = 'gaussian', origin = 'lower', cmap = 'jet')
我可以通过确定每个bin中的最大强度或计数来规范化行,并将其用作参考点并绘制范围为0 - 1的其他数据吗?
注意:这与上述代码无关,但我会附上示例,以便直观地展示我希望实现的目标。我的代码生成以下图像:
虽然不能与上述代码重现,但这些图像是这样产生的:
C_f50,x,y,p = plt.hist2d(Con_F50X, Con_F50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax9.imshow(C_f50.T, interpolation = 'gaussian', cmap = 'jet')
C_fmid,x,y,p = plt.hist2d(Con_FMIDX, Con_FMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax10.imshow(C_fmid.T, interpolation = 'gaussian', cmap = 'jet')
C_dmid,x,y,p = plt.hist2d(Con_DMIDX, Con_DMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax11.imshow(C_dmid.T, interpolation = 'gaussian', cmap = 'jet')
C_d50,x,y,p = plt.hist2d(Con_D50X, Con_D50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax12.imshow(C_d50.T, interpolation = 'gaussian', cmap = 'jet')
下一组图片使用@filippo在答案部分详述的vmin
和vmax
。
正如您所见,密度发生了显着变化。主要区别在于vmin/vmax
功能。它从第一个图(C_f50)获得这些测量值。
我想要了解的是,是否有另一种方法可以从单独的点标准化所有绘图的密度。以上使用了第一个图中的vmin / vmax。但显然,如果从这个图中标准化,密度就不会发生变化。
C_f50,x,y,p = plt.hist2d(Con_F50X, Con_F50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax9.imshow(C_f50.T, interpolation = 'gaussian', cmap = 'jet')
C_fmid,x,y,p = plt.hist2d(Con_FMIDX, Con_FMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax10.imshow(C_fmid.T, interpolation = 'gaussian', cmap = 'jet',vmin=C_f50.min(), vmax=C_f50.max())
C_dmid,x,y,p = plt.hist2d(Con_DMIDX, Con_DMIDY, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax11.imshow(C_dmid.T, interpolation = 'gaussian', cmap = 'jet', vmin=C_f50.min(), vmax=C_f50.max())
C_d50,x,y,p = plt.hist2d(Con_D50X, Con_D50Y, bins = 40, range = np.array([(-85, 85), (4, 140)]))
ax12.imshow(C_d50.T, interpolation = 'gaussian', cmap = 'jet',vmin=C_f50.min(), vmax=C_f50.max())
这有什么意义吗?
答案 0 :(得分:1)
不确定我完全理解这个问题。附图与您发布的代码没有明显的关系。
您可以预先计算直方图,查找最小值和最大值,并使用vmin
和vmax
imshow
参数进行标准化。
E.g。
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
# gen 9 2d gaussian samples and histogram
data = np.random.normal(size=(9, 10000, 2))
zidata = np.asarray([np.histogram2d(row[:,0], row[:,1], bins=40)[0] for row in data])
# plot
gridspec = mpl.gridspec.GridSpec(3,3)
for zi, gs in zip(zidata, gridspec):
ax = plt.subplot(gs)
ax.imshow(zi, interpolation='gaussian', vmin=zidata.min(), vmax=zidata.max())
ax.axis("tight")
plt.show()
默认情况下,imshow会使用Normalize对您的数据进行规范化,这基本上会应用简单的线性转换,如:
vmin = img.min()
vmax = img.max()
return (img - vmin)/(vmax - vmin)
您可以手动更改其行为设置vmin
和vmax
,例如在此示例中将它们设置为所有子图中的全局极值。
或者,如果您需要更多控制权,可以设置norm=matplotlib.colors.NoNorm
并自行规范化数据,以便正确映射到matplotlib色彩映射。