彩色编码的2D直方图

时间:2016-06-17 13:04:54

标签: python-3.x numpy matplotlib histogram

我想绘制一个颜色编码的直方图,我输入一个数组数组来表示y轴上的元素,而x轴上的一个简单的一维数组代表一个相位。

在y轴上绘制的数组数组有一个维度,比如说(100, 25),而x轴上的相位有25个元素。因此,100是必须对25个相位区中的每一个进行颜色编码的元素数。

我认为numpy.hist2d适用于此,但它只需要两个相同大小的数组作为输入。我想我必须为每个25元素的100数组创建一个颜色映射?

我真的不知道如何处理这个问题,因为我根本没有使用彩色编码图的经验。

编辑:我发现this example与我的情况非常接近,除了我想要一个二维图,其中Z维是颜色: enter image description here

此外,不同的直方图需要具有相同的颜色编码。这是我的数据示例:

 phase (X-axis) =  [ 0.01952176  0.04740999  0.07529822  0.10318645  0.13107468  
 0.15896291 0.18685114  0.21473937  0.2426276   0.27051583  0.29840406 
 0.32629229 0.35418052  0.38206875  0.40995698  0.43784521  0.46573344  
 0.49362167 0.5215099   0.54939813  0.57728636  0.60517459  0.63306282  
 0.66095105 0.68883928  0.71672751  0.74461574  0.77250397  0.8003922   
 0.82828043 0.85616866  0.88405689  0.91194512  0.93983335  0.96772158  
 0.99560981] 
 data to be color-coded in histograms (Y-axis) = [[ 0.01011273  0.00237802 -0.00227542 ...,         nan         nan          nan]
 [-0.00407017 -0.00317593 -0.00605734 ...,         nan         nan
      nan]
 [ 0.0166795   0.00798681  0.00075688 ...,         0.01022334         nan
      nan]
 ..., 
 [ 0.00940512         nan         nan ...,         nan         0.00022334
      0.00134779]
 [ 0.00176177  0.00151938         nan ...,         0.05692114         0.00021122
      -0.00003121]
 [        nan  0.00455727         nan ...,         0.06812121         0.00011512
      0.00016711]]

2 个答案:

答案 0 :(得分:3)

也许如果您能提供一些数据示例,我们可以做得更好。 除非我没有完全理解你的问题,否则我认为这可以做你想要的:

data = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,11],[13,14,15]])

#colormap
cm = plt.cm.get_cmap('RdYlBu_r')
norm = matplotlib.colors.Normalize(vmin=data.min(), vmax=data.max())
sm = plt.cm.ScalarMappable(cmap=cm, norm=norm)

fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
for i, l in enumerate(data):
    ax.bar(np.arange(0,len(l)), l, zs=i, zdir='y', alpha=0.8, color=sm.to_rgba(l))

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

enter image description here

答案 1 :(得分:3)

如果我最终理解正确,你有一个数组(25,100),并且你想计算每一行100个数据点的分布。 可能有一种方法可以使用hist2d,但我不知道如何使用它,所以这将是我的方法:

Nphase = 25
Npoints = 100

phase = np.linspace(0.,1.,num=Nphase)
data = np.array([A*np.random.normal(size=(Npoints,))+C for (A,C) in 
                 zip(
            np.random.randint(1,2,Nphase),
            np.random.randint(-5,5,Nphase))])
#sprinkle some NaN
for i,j in zip(np.random.randint(0,Nphase,size=(10,)),np.random.randint(0,Npoints,size=(10,))):
    data[i,j] = np.NaN

您不会对数据的范围或它们相对于彼此的比例进行任何说明。在这里,我将使用20个箱子进行直方图,并且具有相同的限制。

#calculate the bins we're going to use
minBin, maxBin = np.nanmin(data),np.nanmax(data)
Nbins = 20

通过迭代每一行来计算直方图

binedData = np.zeros((Nphase,Nbins))
for i,a in enumerate(data):
    binedData[i,:], bins = np.histogram(a[~np.isnan(a)],bins=Nbins,range=(minBin,maxBin))

情节

plt.matshow(binedData.T, cmap=plt.cm.RdYlBu_r, extent=(0,Nphase,maxBin,minBin))
plt.grid(False)
c = plt.colorbar(orientation='horizontal')
plt.xlabel('Phase')
plt.ylabel('bins')
c.set_label('Frequency')

enter image description here

现在,您提到要对每行进行规范化。有几种方法可以做到这一点,最好的方法是创建一个规范化直方图,其中曲线下面积等于1(参见density histogram参数功能)。 在这里,我假设你只是希望最大化对于可视化来说都是相同的。

# normalize histogram
data2 = 1.*(binedData - np.nanmin(binedData,axis=1, keepdims=True)) / (np.nanmax(binedData,axis=1,keepdims=True)-np.nanmin(binedData,axis=1,keepdims=True))

plt.matshow(data2.T, cmap=plt.cm.RdYlBu_r, extent=(0,Nphase,maxBin,minBin))
plt.grid(False)
c = plt.colorbar(orientation='horizontal')
plt.xlabel('Phase')
plt.ylabel('bins')
c.set_label('Frequency')

enter image description here