我有一组X,Y数据点(大约10k),很容易绘制成散点图,但我想用热图来表示。
我查看了Matplotlib中的示例,它们似乎都已经从热图单元值开始生成图像。
有没有一种方法可以将一堆不同的x, y转换为热图(其中x, y频率较高的区域会“更温暖”)?
我有一组X,Y数据点(大约10k),很容易绘制成散点图,但我想用热图来表示。
我查看了Matplotlib中的示例,它们似乎都已经从热图单元值开始生成图像。
有没有一种方法可以将一堆不同的x, y转换为热图(其中x, y频率较高的区域会“更温暖”)?
当前回答
如果您正在使用1.2.x
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(100000)
y = np.random.randn(100000)
plt.hist2d(x,y,bins=100)
plt.show()
其他回答
非常类似于@Piti的答案,但使用1次调用而不是2次调用来生成点:
import numpy as np
import matplotlib.pyplot as plt
pts = 1000000
mean = [0.0, 0.0]
cov = [[1.0,0.0],[0.0,1.0]]
x,y = np.random.multivariate_normal(mean, cov, pts).T
plt.hist2d(x, y, bins=50, cmap=plt.cm.jet)
plt.show()
输出:
如果你不想要六边形,你可以使用numpy的histogram2d函数:
import numpy as np
import numpy.random
import matplotlib.pyplot as plt
# Generate some test data
x = np.random.randn(8873)
y = np.random.randn(8873)
heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
plt.clf()
plt.imshow(heatmap.T, extent=extent, origin='lower')
plt.show()
这是一个50x50的热图。如果你想要,比如说512x384,你可以在调用histogram2d时放入bins=(512,384)。
例子:
创建一个与最终图像中的单元格对应的二维数组,称为say heatmap_cells,并将其实例化为全零。
选择两个比例因子来定义每个数组元素在实际单位中的差异,对于每个维度,例如x_scale和y_scale。选择这些,使所有数据点都在热图数组的范围内。
对于每个带x_value和y_value的原始数据点:
heatmap_cells[地板(x_value / x_scale),地板(y_value / y_scale)] + = 1
如果您正在使用1.2.x
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(100000)
y = np.random.randn(100000)
plt.hist2d(x,y,bins=100)
plt.show()
最初的问题是…如何将散点值转换为网格值? Histogram2d确实计算每个单元格的频率,但是,如果每个单元格除了频率之外还有其他数据,则需要做一些额外的工作。
x = data_x # between -10 and 4, log-gamma of an svc
y = data_y # between -4 and 11, log-C of an svc
z = data_z #between 0 and 0.78, f1-values from a difficult dataset
我有一个数据集,X和Y坐标的z结果。然而,我计算的是兴趣区域之外的几个点(大的差距),而在一个小的兴趣区域内的一堆点。
是的,在这里它变得更困难,但也更有趣。一些库(抱歉):
from matplotlib import pyplot as plt
from matplotlib import cm
import numpy as np
from scipy.interpolate import griddata
Pyplot是我今天的图形引擎, Cm是一个彩色地图的范围,有一些有趣的选择。 Numpy来计算, 和griddata用于将值附加到固定网格。
最后一点很重要,因为xy点的频率在我的数据中不是均匀分布的。首先,让我们从适合我的数据和任意网格大小的边界开始。原始数据的数据点也在这些x和y边界之外。
#determine grid boundaries
gridsize = 500
x_min = -8
x_max = 2.5
y_min = -2
y_max = 7
所以我们已经定义了一个在x和y的最小值和最大值之间有500像素的网格。
在我的数据中,在高度感兴趣的领域,有超过500个可用值;而在低兴趣区域,整个网格中甚至没有200个值;在x_min和x_max的图形边界之间就更少了。
因此,要得到一张漂亮的图片,任务就是求出高兴趣值的平均值,并填补其他地方的空白。
我现在定义我的网格。对于每一对xx-yy,我想有一个颜色。
xx = np.linspace(x_min, x_max, gridsize) # array of x values
yy = np.linspace(y_min, y_max, gridsize) # array of y values
grid = np.array(np.meshgrid(xx, yy.T))
grid = grid.reshape(2, grid.shape[1]*grid.shape[2]).T
为什么会有这么奇怪的形状?scipy。griddata需要一个(n, D)的形状。
Griddata通过预定义的方法计算网格中的每个点的值。 我选择“最近”-空网格点将被来自最近邻居的值填充。这看起来好像信息较少的区域有更大的细胞(即使事实并非如此)。人们可以选择插值“线性”,那么信息较少的区域看起来不那么清晰。这是品味问题,真的。
points = np.array([x, y]).T # because griddata wants it that way
z_grid2 = griddata(points, z, grid, method='nearest')
# you get a 1D vector as result. Reshape to picture format!
z_grid2 = z_grid2.reshape(xx.shape[0], yy.shape[0])
跳跃时,我们交给matplotlib来显示图
fig = plt.figure(1, figsize=(10, 10))
ax1 = fig.add_subplot(111)
ax1.imshow(z_grid2, extent=[x_min, x_max,y_min, y_max, ],
origin='lower', cmap=cm.magma)
ax1.set_title("SVC: empty spots filled by nearest neighbours")
ax1.set_xlabel('log gamma')
ax1.set_ylabel('log C')
plt.show()
在v型的尖端部分,你可以看到,我在寻找最佳点的过程中做了很多计算,而几乎所有其他地方的不太有趣的部分都有较低的分辨率。