使用散点图在颜色条上显示所有颜色

Show all colors on colorbar with scatter plot

在下文中,我使用散点图和自己的 ListedColormap 来绘制一些彩色数据点。另外对应的colorbar也画出来了。

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, ListedColormap, BoundaryNorm
from numpy import arange

fig, ax = plt.subplots()

my_cm = ListedColormap(['#a71b1b','#94258f','#ea99e6','#ec9510','#ece43b','#a3f8ff','#2586df','#035e0d'])
bounds=range(8)
norm = BoundaryNorm(bounds, my_cm.N)

data = [1,2,1,3,0,5,3,4]
ret = ax.scatter(range(my_cm.N), [1]*my_cm.N, c=data, edgecolors='face', cmap=my_cm, s=50)
cbar = fig.colorbar(ret, ax=ax, boundaries=arange(-0.5,8,1), ticks=bounds, norm=norm)
cbar.ax.tick_params(axis='both', which='both',length=0)

如果我的数据没有覆盖边界区间的每个值,colorbar 不会显示所有颜色(如添加的图中所示)。如果 data 设置为 range(8),我会得到每种颜色的点,colorbar 也会显示所有颜色。

即使 data 不包含所有边界值,我如何强制 colorbar 显示所有定义的颜色?

您需要在调用 ax.scatter 时手动设置 vminvmax:

ret = ax.scatter(range(my_cm.N), [1]*my_cm.N, c=data, edgecolors='face', cmap=my_cm, s=50, vmin=0, vmax=7)

导致

If my data is not covering each value of the boundary interval, the colorbar does not show all colours (like in the added figure).

如果 vminvmax 是 `None 颜色限制是通过方法设置的 autoscale_None,因此会使用您数据的最小值和最大值。

因此,使用您的代码,实际上没有必要在颜色条中显示所有颜色,以覆盖边界间隔的每个值,只需要包括最小值和最大值。 使用例如data = [0,0,0,0,0,0,0,7] 结果如下:

在寻找其他东西时,我找到了该问题的另一个解决方案:colorbar-for-matplotlib-plot-surface-command。 在那种情况下,我不需要设置 vminvmax 并且如果要绘制的点的 arrays/lists 为空,它也可以工作。相反,ScalarMappable 被定义并提供给 colorbar 而不是 scatter 实例。

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, ListedColormap, BoundaryNorm
import matplotlib.cm as cm
from numpy import arange

fig, ax = plt.subplots()

my_cm = ListedColormap(['#a71b1b','#94258f','#ea99e6','#ec9510','#ece43b','#a3f8ff','#2586df','#035e0d'])
bounds=range(8)
norm = BoundaryNorm(bounds, my_cm.N)
mappable = cm.ScalarMappable(cmap=my_cm)
mappable.set_array(bounds)

data = [] # also x and y can be []
ax.scatter(x=range(my_cm.N), y=[1]*my_cm.N, c=data, edgecolors='face', cmap=my_cm, s=50)
cbar = fig.colorbar(mappable, ax=ax, boundaries=arange(-0.5,8,1), ticks=bounds, norm=norm)
cbar.ax.tick_params(axis='both', which='both',length=0)