使用散点数据集在MatPlotLib中生成热图

我有一组X,Y数据点(大约10k),这些数据点很容易作为散点图进行绘制,但我想将其表示为热图。

我查看了MatPlotLib中的例子,他们似乎都已经开始使用热图单元格值来生成图像。

有没有一种方法可以将一堆x,y,所有不同的东西都转换成热图(其中x,y的频率更高的区域会变得更暖和)?

如果你不想要六边形,你可以使用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() 

这使得50×50热图。 如果你想,比如说512×384,你可以把bins=(512, 384) 512,384 bins=(512, 384)放到histogram2d的调用中。

例: Matplotlib热图例子

Matplotlib词典中,我想你想要一个hexbin图。

如果你不熟悉这种types的情节,那只是一个双variables直方图 ,其中xy平面是由一个规则的六边形网格镶嵌的。

因此,从直方图中,您可以计算每个六边形中落入的点的数量,将绘图区域离散为一组窗口 ,将每个点分配给这些窗口中的一个; 最后,将窗口映射到一个颜色数组 ,并且有一个hexbin图。

尽pipe比圆形或正方形不太常用,但是对于装箱容器的几何形状而言,六边形是更好的select,这是直观的:

  • 六边形具有最近邻近的对称性 (例如,方形箱不是,例如正方形的边界的点到该正方形内的点的距离并不是每个地方都是相等的)和

  • 六边形是最高的n多边形,可以定期进行平面镶嵌 (也就是说,您可以安全地用六angular形瓷砖重新塑造您的厨房地板,因为当您完成后,瓷砖之间不会有任何空隙空间 – 对于所有其他更高的n,n> = 7,多边形)。

Matplotlib使用hexbin图;所以(AFAIK)所有的绘图库的R ;我不知道这是否是这种types的情节通常接受的术语,但我怀疑这可能是因为hexbin很短用于六边形分箱 ,这是描述准备显示数据的基本步骤。)


 from matplotlib import pyplot as PLT from matplotlib import cm as CM from matplotlib import mlab as ML import numpy as NP n = 1e5 x = y = NP.linspace(-5, 5, 100) X, Y = NP.meshgrid(x, y) Z1 = ML.bivariate_normal(X, Y, 2, 2, 0, 0) Z2 = ML.bivariate_normal(X, Y, 4, 1, 1, 1) ZD = Z2 - Z1 x = X.ravel() y = Y.ravel() z = ZD.ravel() gridsize=30 PLT.subplot(111) # if 'bins=None', then color of each hexagon corresponds directly to its count # 'C' is optional--it maps values to xy coordinates; if 'C' is None (default) then # the result is a pure 2D histogram PLT.hexbin(x, y, C=z, gridsize=gridsize, cmap=CM.jet, bins=None) PLT.axis([x.min(), x.max(), y.min(), y.max()]) cb = PLT.colorbar() cb.set_label('mean value') PLT.show() 

在这里输入图像描述

我不想使用np.hist2d,它通常产生相当丑陋的直方图,我想回收py-sphviewer ,一个使用自适应平滑内核来渲染粒子模拟的Python包,可以通过pip轻松安装(请参阅网页文档)。 考虑下面的代码,它基于这个例子:

 import numpy as np import numpy.random import matplotlib.pyplot as plt import sphviewer as sph def myplot(x, y, nb=32, xsize=500, ysize=500): xmin = np.min(x) xmax = np.max(x) ymin = np.min(y) ymax = np.max(y) x0 = (xmin+xmax)/2. y0 = (ymin+ymax)/2. pos = np.zeros([3, len(x)]) pos[0,:] = x pos[1,:] = y w = np.ones(len(x)) P = sph.Particles(pos, w, nb=nb) S = sph.Scene(P) S.update_camera(r='infinity', x=x0, y=y0, z=0, xsize=xsize, ysize=ysize) R = sph.Render(S) R.set_logscale() img = R.get_image() extent = R.get_extent() for i, j in zip(xrange(4), [x0,x0,y0,y0]): extent[i] += j print extent return img, extent fig = plt.figure(1, figsize=(10,10)) ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222) ax3 = fig.add_subplot(223) ax4 = fig.add_subplot(224) # Generate some test data x = np.random.randn(1000) y = np.random.randn(1000) #Plotting a regular scatter plot ax1.plot(x,y,'k.', markersize=5) ax1.set_xlim(-3,3) ax1.set_ylim(-3,3) heatmap_16, extent_16 = myplot(x,y, nb=16) heatmap_32, extent_32 = myplot(x,y, nb=32) heatmap_64, extent_64 = myplot(x,y, nb=64) ax2.imshow(heatmap_16, extent=extent_16, origin='lower', aspect='auto') ax2.set_title("Smoothing over 16 neighbors") ax3.imshow(heatmap_32, extent=extent_32, origin='lower', aspect='auto') ax3.set_title("Smoothing over 32 neighbors") #Make the heatmap using a smoothing over 64 neighbors ax4.imshow(heatmap_64, extent=extent_64, origin='lower', aspect='auto') ax4.set_title("Smoothing over 64 neighbors") plt.show() 

这会产生下面的图像:

在这里输入图像描述

如您所见,图像看起来相当不错,我们能够识别不同的子结构。 这些图像被构造为对于某个域内的每个点扩展一个给定的权重,由平滑长度定义,这个距离又由距离较近的邻居(我已经select了16,32和64的例子)给出。 所以,与较低密度区域相比,较高密度区域通常分布在较小区域上。

函数myplot只是一个非常简单的函数,为了给x,y数据提供py-sphviewer来完成这个魔术。

如果你正在使用1.2.x

 x = randn(100000)
 y = randn(100000)
 hist2d(X,Y,频段= 100);

在这里输入图像描述

Seaborn现在有联合作用function ,在这里应该很好地工作:

 import numpy as np import seaborn as sns import matplotlib.pyplot as plt # Generate some test data x = np.random.randn(8873) y = np.random.randn(8873) sns.jointplot(x=x, y=y, kind='hex') plt.show() 

演示图像

创build一个与最终图像中的单元格对应的二维数组,称为heatmap_cells并将其实例化为全零。

select两个比例因子来定义每个数组元素之间的实际单位差异,例如x_scaley_scale 。 select这些,使所有的数据点落在热图数组的范围内。

对于具有x_valuey_value每个原始数据点:

heatmap_cells[floor(x_value/x_scale),floor(y_value/y_scale)]+=1

Interesting Posts