我找到了做我所要求的事情的方法。
这个想法是创建一个新变量,该变量取决于每组中向量的数量,并使用该变量spacing='proportional'
。这是 MWE:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as colors
fig = plt.figure(figsize=(10,7))
ax = fig.add_subplot()
category = np.array([0,0,0,0.1,0.4,0.9,1.5])
r = np.random.uniform(size=[len(category)*100]).reshape(len(category),100)
norm = matplotlib.colors.Normalize(vmin=min(category), vmax=max(category))
lev1 = 0.3
lev2 = 0.5
gr0 = (category<=lev1).sum()
gr2 = (category>lev2).sum()
gr1 = len(category) - gr0 - gr2
frac = np.array([gr0,gr1,gr2])/len(category)
bounds = np.array([0, frac[0], frac[1]+frac[0], 1])
gr_color = np.where(category<lev1,0,np.where(category>=lev2,1,frac[0]+frac[1]/2))
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=3)
cmap = matplotlib.cm.ScalarMappable(norm=norm, cmap=colors.ListedColormap(['green', 'blue', 'red']))
cmap.set_array([])
for no, cat in enumerate(category):
ax.plot(r[no][r[no]>0.1],no*np.ones(100)[r[no]>0.1],'o',color=cmap.to_rgba(gr_color[no]))
cbar = fig.colorbar(cmap, ax=ax, pad=0.01,spacing='proportional')
dic = {bounds[0] : 0 ,bounds[1] : lev1, bounds[2] : lev2,bounds[3] : "1.5"}
labels = [bounds[i] if t not in dic.keys() else dic[t] for i,t in enumerate(bounds)]
cbar.ax.set_yticklabels(labels)