开发者

Color handling in Python

开发者 https://www.devze.com 2023-01-16 01:18 出处:网络
For my clustering gui, I am currently using random colors for the clusters, since I won\'t know before hand how many clusters I will end up with.

For my clustering gui, I am currently using random colors for the clusters, since I won't know before hand how many clusters I will end up with.

In Python, this looks like:

import random
def randomColor():
    return (random.random(),random.random(),random.random())

However, when I update things, the colors change.

So what I would开发者_Python百科 favor is to have a function which has an input argument I such as

def nonrandomColor(i):
   ...
   return color

would always return the same color for the same I, while keeping the ability to generate arbitrarily many colors.

Answer does not have to be formulated in Python, it's more the general layout I'm interested in.


One way is to use caching. Use a defaultdict:

>>> import random
>>> def randomColor():
...    return (random.random(),random.random(),random.random())
... 
>>> from collections import defaultdict
>>> colors = defaultdict(randomColor)
>>> colors[3]
(0.10726172906719755, 0.97327604757295705, 0.58935794305308264)
>>> colors[1]
(0.48991106537516382, 0.77039712435566876, 0.73707003166893892)
>>> colors[3]
(0.10726172906719755, 0.97327604757295705, 0.58935794305308264)


Just set the seed of the random generator to the index, this might be cheaper than storing the colors.

random.seed(i)

Note that this will make random numbers way less random than before. If that is a problem, e.g. if your application uses random numbers elsewhere, you might want to look into the caching options suggested by other answers.


If you want repeatable non colliding colors then you could use something like the function below. It sections the number into 1, 10, 100 and then uses them as the RGB parts of the color.

def color(i):
  r = i % 10
  g = (i//10) % 10
  b = (i//100) % 10
  return(r*25, g*25, b*25)

For example:

color(1) == (25,0,0)
color(10) == (0,25,0)
color(999) = (225,225,255)


You want to store the colors in a dictionary or a list:

colors = {} # int -> color
def nonrandomColor(i):
   if i not in colors:
      colors[i] = randomColor()
   return colors[i] 


You can use i to seed the random number generator. So, as long as the seed remains the same, you get the same value.

>>> import random
>>> random.seed(12)
>>> random.randint(0,255), random.randint(0,255), random.randint(0,255)
(121, 168, 170)
>>> random.seed(12)
>>> random.randint(0,255), random.randint(0,255), random.randint(0,255)
(121, 168, 170)
>>> random.seed(10)
>>> random.randint(0,255), random.randint(0,255), random.randint(0,255)
(146, 109, 147)
>>> random.seed(10)
>>> random.randint(0,255), random.randint(0,255), random.randint(0,255)
(146, 109, 147)

Depending on the number of colours you're likely to generate (i.e., 10 or a million), the caching method might be better than the seed() method.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号