Color-coded 2D histogram

﹥>﹥吖頭↗ 提交于 2019-12-10 12:26:45

问题


I want to plot a color-coded histogram, where I input an array of arrays to represent the elements on the y-axis, while a simple 1D array on the x-axis to represent a phase.

The array of arrays to plot on the y-axis has a dimension, let's say, (100, 25), while the phase on the x-axis has 25 elements. Therefore, 100 is the number of elements that have to be color-coded for each of the 25 phase-bins.

I thought numpy.hist2d was suitable for this, but it only takes two same-sized arrays as input. I suppose I have to create a map of colors for each of the 25 arrays of 100 elements?

I really do not know how to approach this, because I have no experience with color-coded plots at all.

EDIT: I found this example as quite close to my case, except that I want a 2D plot where the Z-dimension is the color:

Also, the different histograms need to have the same color-coding. Here an example of my data:

 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]]

回答1:


If I understood correctly in the end, you have an array (25,100), and you want to calculate the distribution of the 100 data points for each row. There's probably a way to use hist2dfor this, but I don't know how to use it, so here would be my method:

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

You don't say anything about the range of your data, or how they scale relative to one another. Here I'm going to do an histogram with 20 bins, and with the same limits.

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

calculate the histogram by iterating over each row

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))

an plot

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')

Now, you mentioned that you want to normalize each row. There are several ways to do this, the best way would be to create a normalized histogram where the area under the curve is equal to 1 (see density argument to the histogram function). Here I assumed you just want the max to all be equal for visualisation sake.

# 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')




回答2:


maybe if you could provide some example of your data, we could do better. Unless I did not fully understand your question, I think this does what you want:

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')



来源:https://stackoverflow.com/questions/37882325/color-coded-2d-histogram

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!