根据值的范围更改颜色图中的颜色

Change colors in colormap based on range of values

是否可以根据值的范围设置颜色条的下部 and/or 上部?例如,给定下面的 ROYGBIV 颜色图以及可选的 offsetrange 值,我想更改 offset and/or 以下 range 以上的颜色.换句话说,假设 offset = 20range = 72,我想将所有小于或等于 20 的值涂成黑色,所有大于或等于 72 的值涂成白色。我知道 set_underset_over 方法,但它们需要更改参数 vminvmax(据我所知),这不是我想要的.我想保留原来的最小值和最大值(例如 vmin = 0vmax = 100),并且只(可选)更改四肢的颜色。

ROYGBIV = {
    "blue": ((0.0, 1.0, 1.0),
             (0.167, 1.0, 1.0),
             (0.333, 1.0, 1.0),
             (0.5, 0.0, 0.0),
             (0.667, 0.0, 0.0),
             (0.833, 0.0, 0.0),
             (1.0, 0.0, 0.0)),
    "green": ((0.0, 0.0, 0.0),
              (0.167, 0.0, 0.0),
              (0.333, 0.0, 0.0),
              (0.5, 1.0, 1.0),
              (0.667, 1.0, 1.0),
              (0.833, 0.498, 0.498),
              (1.0, 0.0, 0.0)),
    "red": ((0.0, 0.5608, 0.5608),
            (0.167, 0.4353, 0.4353),
            (0.333, 0.0, 0.0),
            (0.5, 0.0, 0.0),
            (0.667, 1.0, 1.0),
            (0.833, 1.0, 1.0),
            (1.0, 1.0, 1.0))
}

rainbow_mod = matplotlib.colors.LinearSegmentedColormap("rainbow_mod", ROYGBIV, 256)

我找到了一种使用 ListedColormap 的方法,如 here 所述。基本思想是获取 LinearSegmentedColormap 对象(numpy 数组)中颜色的 RGBA lists/tuples,并用所需颜色的副本替换第一个或最后几个列表。

看起来像这样:

under_color = [0.0, 0.0, 0.0, 1.0]  # black (alpha = 1.0)
over_color = [1.0, 1.0, 1.0, 1.0]  # white (alpha = 1.0)

all_colors = rainbow_mod(np.linspace(0, 1, 256))

vmin = 0.0
vmax = 100.0

all_colors[:int(np.round((20.0 - vmin) / (vmax - vmin) * 256)), :] = under_color
all_colors[int(np.round((72.0 - vmin) / (vmax - vmin) * 256)):, :] = over_color

rainbow_mod_list = matplotlib.colors.ListedColormap(all_colors.tolist())