问题
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