如何将 5 个数字映射到 5 种不同的颜色

How to map 5 numbers to 5 different colors

我有一个关于颜色图管理的问题。

在下图中,显示的每个点都与一个值相关联:2、3、4、5 或 13。

因此,为了了解与每个点关联的值,我使用了颜色图选项。我生成了 5 种颜色的颜色图,一种颜色与每个值相关联。

问题是值 2、3 和 4 与紫色相关联,值 5 与蓝色相关联,值 13 与红色相关联。事实上,颜色图包含 5 种颜色,但右侧标签的比例从 2 到 13。

但是,我希望 2 与紫色相关联,3 与蓝色相关联,4 与绿色相关联,5 与橙色相关联,13 与红色相关联。

我的代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat May 14 15:04:21 2022

@author: cldelh
"""

import numpy             as np
import matplotlib.pyplot as plt
from matplotlib.pyplot   import cm

# Abscisses
W = np.array([0.        , 0.01      , 0.01999402, 0.03412597, 0.05410511,
          0.08232443, 0.12194226, 0.16661301, 0.20758763, 0.23904194,
          0.24626125, 0.25039445, 0.25330903, 0.25582872, 0.25816522,
          0.26031379, 0.26266544, 0.26568211, 0.27005595, 0.2770875 ,
          0.28909234, 0.30636753, 0.32544111, 0.34694002, 0.36917884,
          0.3897257 , 0.40656458, 0.41784063, 0.42541583, 0.43055847,
          0.43452519, 0.43742307, 0.43919769, 0.44031273, 0.44112462,
          0.44200454, 0.44347889, 0.44643343, 0.45229159, 0.46288266,
          0.48056282, 0.50895736, 0.54927625, 0.59608409, 0.64487664,
          0.7016973 , 0.76708481, 0.84185322, 0.92696579, 1.01707062,
          1.10557259, 1.19256251, 1.27815237, 1.36244217, 1.44550112,
          1.52735963, 1.60800828, 1.68740049, 1.76545689, 1.84207015,
          1.91710981, 1.99042675, 2.06185747, 2.13122796, 2.1983573 ,
          2.263061  , 2.32515405, 2.38445365, 2.44078163, 2.49396659,
          2.54384564, 2.5902658 , 2.63308518, 2.67217368, 2.70741361,
          2.73869997, 2.76594058, 2.78905614, 2.80798011, 2.82265863,
          2.83305046, 2.83912688, 2.84087179, 2.83828174, 2.83136621,
          2.82014797, 2.80466344, 2.78496333, 2.76111323, 2.73319431,
          2.70130406, 2.665557  , 2.62608541, 2.58303999, 2.53659044,
          2.48692603, 2.43425621, 2.3788113 , 2.32084358, 2.26062905,
          2.1984705 , 2.13470266, 2.06970116, 2.0038978 , 1.93780705,
          1.87207326, 1.80755842, 1.74551542, 1.68795847, 1.63852865,
          1.60461127, 1.60094385, 1.64165693, 1.71498642, 1.80255956,
          1.89604738, 1.99229146, 2.08996895, 2.18845668, 2.28743203,
          2.38671536, 2.48620089, 2.58582339, 2.68554117, 2.78532671,
          2.8851614 , 2.98503236, 3.08493046])

# Ordonnées
Xinf = np.array([0.36001558, 0.36002501, 0.36005669, 0.36013731, 0.36031898,
             0.36062301, 0.36527713, 0.36485195, 0.38101038, 0.39612248,
             0.40736786, 0.41642505, 0.42372367, 0.4296357 , 0.4329689 ,
             0.43243038, 0.42777775, 0.41881406, 0.4058955 , 0.39050351,
             0.37868412, 0.37464251, 0.3753022 , 0.38049347, 0.39215149,
             0.41261855, 0.44186649, 0.47214887, 0.50022204, 0.52476197,
             0.54846522, 0.57015033, 0.58647846, 0.59804236, 0.60505114,
             0.60736793, 0.60431747, 0.59481333, 0.57794772, 0.55477589,
             0.52875494, 0.50564226, 0.49269248, 0.49103505, 0.49670408,
             0.50868991, 0.52725566, 0.55320582, 0.58777717, 0.62935965,
             0.67447035, 0.72228144, 0.77209809, 0.82333207, 0.87550968,
             0.92821221, 0.98109947, 1.03388713, 1.08631077, 1.13814125,
             1.18917466, 1.23921078, 1.28807521, 1.33558548, 1.38158777,
             1.42589996, 1.46839252, 1.50890861, 1.54730779, 1.58347723,
             1.61727155, 1.64859434, 1.67732612, 1.70338193, 1.72667917,
             1.74713082, 1.76466827, 1.77924246, 1.79079041, 1.79926455,
             1.80462534, 1.80686203, 1.80593978, 1.80183511, 1.79455897,
             1.78410278, 1.77046371, 1.75366114, 1.733729  , 1.7106789 ,
             1.68454743, 1.65537695, 1.62321454, 1.58811057, 1.55013282,
             1.50933504, 1.46577577, 1.41951312, 1.37061227, 1.31911356,
             1.2650476 , 1.20840623, 1.14917691, 1.08726763, 1.02253009,
             0.95471075, 0.88341169, 0.8079946 , 0.72748982, 0.64047401,
             0.54539278, 0.44410944, 0.35174988, 0.28325452, 0.23475268,
             0.19915439, 0.17195691, 0.15050578, 0.13316766, 0.11888317,
             0.10692915, 0.09679719, 0.08811551, 0.08060803, 0.07406247,
             0.06831513, 0.06323702, 0.05872426])

# Variables
variable = np.array([ 5.,  2.,  2.,  2.,  2.,  2.,  3.,  4.,  5.,  5., 13.,  4.,  3.,
                 3.,  4.,  4.,  4.,  4.,  4.,  4.,  4.,  4.,  3.,  3.,  3.,  3.,
                 4.,  4.,  4.,  3.,  3.,  4.,  4.,  4.,  4.,  4.,  4.,  4.,  4.,
                 4.,  4.,  4.,  4.,  4.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,
                 3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,
                 3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,
                 3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,
                 3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,
                 3.,  3.,  3.,  3.,  3.,  3.,  3.,  4.,  4.,  4.,  4.,  3.,  3.,
                 3.,  3.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.])

# Valeurs contenues dans variable
variable_delete = np.array([ 5.,  2.,  3.,  4., 13.])

# Points
plt.scatter(W,Xinf,s=10,marker='o', c=variable, cmap=cm.get_cmap('rainbow', len(variable_delete)))

# Colorbar
cb = plt.colorbar(ticks=variable_delete, location='right', label=r'$k_{iter} \; [\emptyset]$')

以下方法首先将 5 个等距点定位到 0 到 1 的范围(默认颜色图范围)。然后它将 5 个 variable_delete 值中的每一个映射到其对应的位置。这些映射值用于着色。之后,颜色条位置得到相应的标记。

当数字标签为随机顺序时,该代码也有效。

(另一种方法是使用 BoundaryNorm,但要准确定位标签会变得更加复杂。)

import numpy             as np
import matplotlib.pyplot as plt

# W = ...
# Xinf = ...
# variable = ...

variable_delete = np.array([2., 3., 4., 5., 13.])

cbar_spots = np.linspace(0, 1, 2 * len(variable_delete) + 1)[1::2]
cbar_dict = {var: spot for var, spot in zip(variable_delete, cbar_spots)}
var_mapped = np.zeros_like(variable)
for k, v in cbar_dict.items():
    var_mapped[variable == k] = v

plt.scatter(W, Xinf, s=10, marker='o', c=var_mapped,
            cmap=plt.get_cmap('rainbow', len(variable_delete)), vmin=0, vmax=1)

cb = plt.colorbar(ticks=cbar_spots, location='right', label=r'$k_{iter} \; [\emptyset]$')
cb.set_ticklabels(variable_delete.astype(int).astype(str))

plt.show()

我可以推荐一个简单的颜色贴图替代方案吗?

In [26]: for v in sorted(variable_delete):
    ...:      ix = variable == v
    ...:      plt.scatter(W[ix], Xinf[ix], s=6, marker='o', label='%3.1f'%v)
    ...: plt.legend()
    ...: plt.grid()