这让我非常不安,我写了get_cmap_string,它返回一个与cmap 完全相同但也作用于字符串的函数。
data = ["bob", "joe", "pete", "andrew", "pete"]
cmap = get_cmap_string(palette='viridis', domain=data)
cmap("joe")
# (0.20803, 0.718701, 0.472873, 1.0)
cmap("joe", alpha=0.5)
# (0.20803, 0.718701, 0.472873, 0.5)
1。实施
所有其他答案提到的基本思想是我们需要一个哈希表——从我们的字符串到整数的映射,它是唯一的。在 python 中,这只是一个字典。
hash(str) 不起作用的原因是,即使 matplotlib 的 cmap 接受任何整数,两个不同的字符串也有可能获得相同的颜色。例如,如果hash(str1) 是8 并且hash(str2) 是18,我们将cmap 初始化为get_cmap(name=palette, lut=10) 那么cmap(hash(str1)) 将与cmap(hash(str2)) 相同
代码
import numpy as np
import matplotlib.cm
def get_cmap_string(palette, domain):
domain_unique = np.unique(domain)
hash_table = {key: i_str for i_str, key in enumerate(domain_unique)}
mpl_cmap = matplotlib.cm.get_cmap(palette, lut=len(domain_unique))
def cmap_out(X, **kwargs):
return mpl_cmap(hash_table[X], **kwargs)
return cmap_out
2。用法
与其他答案中的示例相同,但现在请注意名称 pete 出现了两次。
import matplotlib.pyplot as plt
# data
names = ["bob", "joe", "pete", "andrew", "pete"]
# color map for the data
cmap = get_cmap_string(palette='viridis', domain=names)
# example usage
x = np.linspace(0, np.pi*2, 100)
for i_name, name in enumerate(names):
plt.plot(x, np.sin(x)/i_name, label=name, c=cmap(name))
plt.legend()
plt.show()
您可以看到,图例中的条目是重复的。解决这个问题是另一个挑战,请参阅here。
或者按照here 的说明使用自定义图例。
3。替代品
就 matplotlib 开发人员的讨论而言,他们建议使用 Seaborn。
请参阅讨论 here 和示例用法 here。