我有一个坐标列表:
y,x
445.92,483.156
78.273,321.512
417.311,204.304
62.047,235.216
87.24,532.1
150.863,378.184
79.981,474.14
258.894,87.74
56.496,222.336
85.105,454.176
80.408,411.672
90.656,433.568
378.027,441.296
433.964,290.6
453.606,317.648
383.578,115.432
128.232,312.496
116.276,93.536
94.072,222.336
52.226,327.308
321.663,187.56
392.972,279.008
我想使用matplotlib根据这些点绘制密度图(或热图)。我正在使用pcolormesh和contourf。 我的问题是pcolormesh没有相同的音高大小:
这是代码:
x, y = np.genfromtxt('pogba_t1314.csv', delimiter=',', unpack=True)
#print(x[1], y[1])
y = y[np.logical_not(np.isnan(y))]
x = x[np.logical_not(np.isnan(x))]
k = gaussian_kde(np.vstack([x, y]))
xi, yi = np.mgrid[x.min():x.max():x.size**0.5*1j,y.min():y.max():y.size**0.5*1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))
fig = plt.figure(figsize=(9,10))
ax1 = fig.add_subplot(211)
ax1.pcolormesh(xi, yi, zi.reshape(xi.shape), alpha=0.5)
ax1.plot(y,x, "o")
ax1.set_xlim(0, 740)
ax1.set_ylim(515, 0)
#overlay soccer field
im = plt.imread('statszone_football_pitch.png')
ax1.imshow(im, extent=[0, 740, 0, 515], aspect='auto')
fig.savefig('pogba1516.png')
这是csv文件的链接:https://dl.dropboxusercontent.com/u/12348226/pogba_t1314.csv
答案 0 :(得分:7)
这有望让您开始走上正轨,但我绝对建议您阅读pcolor
和pcolormesh
的文档。
您评论了# Plot the density map using nearest-neighbor interpolation
,但由于Z
是一维数组,因此密度图没有任何二维密度数据。使用np.histogram2d
最容易创建密度贴图,我将在下面使用您的数据显示。
Z, xedges, yedges = np.histogram2d(x, y)
Z
现在是一个2D数组,其中包含有关x,y坐标分布的信息。可以使用pcolormesh
绘制此分布,如此
plt.pcolormesh(xedges, yedges, Z.T)
在获得与您发布的图像类似的图像之前,先选择一种方法,但它应该解释您的错误并帮助您走上正确的轨道。
更新:更好,更平滑的密度图
假设您有两个1D数组,x
和y
,您可以使用内核密度估算以下列方式获得更好的热图 [reference],
from scipy.stats.kde import gaussian_kde
k = gaussian_kde(np.vstack([x, y]))
xi, yi = np.mgrid[x.min():x.max():x.size**0.5*1j,y.min():y.max():y.size**0.5*1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))
现在你可以使用pcolormesh
或contourf
绘制高斯KDE,具体取决于你追求的效果/美学效果
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(7,8))
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
# alpha=0.5 will make the plots semitransparent
ax1.pcolormesh(xi, yi, zi.reshape(xi.shape), alpha=0.5)
ax2.contourf(xi, yi, zi.reshape(xi.shape), alpha=0.5)
ax1.set_xlim(x.min(), x.max())
ax1.set_ylim(y.min(), y.max())
ax2.set_xlim(x.min(), x.max())
ax2.set_ylim(y.min(), y.max())
# you can also overlay your soccer field
im = plt.imread('soccerPitch.jpg')
ax1.imshow(im, extent=[x.min(), x.max(), y.min(), y.max()], aspect='auto')
ax2.imshow(im, extent=[x.min(), x.max(), y.min(), y.max()], aspect='auto')
我得到这张图片: