将任意长度的元组映射到RGB值

0 投票
2 回答
621 浏览
提问于 2025-04-18 06:10

我需要把一组整数(称为元组)转换成RGB颜色值,这些元组的长度可以是任意的,但要保持一致。如果能按照大小顺序排列这些颜色值,那就更好了,特别是在(0,1)和(1,0)之间选择次序的标准方式。

现在我这样做:

  1. 我有一长串颜色的RGB值。

    colors = [(0,0,0),(255,255,255),...]
    
  2. 我把元组的哈希值对颜色数量取模,然后用这个值作为索引。

    def tuple_to_rgb(atuple):
        index = hash(atuple) % len(colors)
        return colors[index]
    

这样做还可以,但我希望它更像热图的值,比如(5,5,5)的值要比(0,0,0)大,这样相邻的颜色就有意义了,值越大颜色就越“热”。

我知道怎么把整数映射到RGB值,所以如果我能找到一种方法,先按元组的大小排序,然后再按内部值排序生成一个唯一的整数,那可能就能实现了。

我可以自己写一个排序比较器,提前生成所有可能的元组列表,然后用列表中的顺序作为唯一整数,但如果不需要提前生成所有可能的元组,那就简单多了。

有没有人有建议?这看起来是可以做到的,我会很感激任何能让我朝正确方向前进的提示。

对那些感兴趣的人来说,我正在尝试可视化量子点的电子占据预测,就像在这篇论文的图1b中那样,但数量可以是任意的(因此元组长度也是任意的)。在代码的特定应用中,元组长度是固定的,但我不想让代码只适用于双点或三点。可能不会超过四个点,但实验人员会想出一些非常奇特的系统。

2 个回答

0

这里有一种替代的方法。之前我生成的点只包含了一部分可能的职业,所以颜色图看起来有些偏差,效果不太好。这个方法需要提前准备一个可能的状态列表,然后把它传入,这样生成的颜色图效果会好很多。

class Colormapper2:
    """
    Like Colormapper, but uses a list of possible occupations to
    generate the maps, rather than generating all possible occupations.
    The difference is that the systems I've explored only have a subset
    of the possible states occupied, and the colormaps look better 
    this way.
    """
    def __init__(self,occs,**kwargs):
        import matplotlib.pyplot as plt
        colormap = kwargs.get('colormap','hot')
        self.occs = sorted(list(occs),key=sum)
        self.n = float(len(self.occs))
        self.cmap = plt.get_cmap(colormap)
        return

    def __call__(self,occ):
        ind255 = int(255*self.occs.index(occ)/self.n)
        return self.cmap(ind255)

下面是生成的图像示例:

双点稳定性图

你可以看到,这里的颜色分布比之前的版本要好得多。

0

这是我写的代码:

class Colormapper:
    """
    Create a colormap to map tuples onto RGBA values produced by matplolib's
    cmap function.

    Arguments are the maximum value of each place in the tuple. Dimension of
    the tuple is inferred from the length of the args array.
    """
    def __init__(self,*args):
        from itertools import product
        import matplotlib.pyplot as plt

        self.occs = sorted(list(product(*[xrange(arg+1) for arg in args])),key=sum)
        self.n = float(len(self.occs))
        self.hotmap = plt.get_cmap('hot')
        return

    def __call__(self,occ):
        ind255 = int(255*self.occs.index(occ)/self.n)
        return self.hotmap(ind255)

下面是这段代码运行后的结果示例:

双点稳定性图

撰写回答