5

I want to know how I can get a color depending on a value between [0-100] where 0 is red and 1 is green and I want values between them to be interpolated colors between red and green (orange, yellow...,..). I'm using python in Blender 3D. The below lines of code can generate rainbow colors as shown here but I wonder how I can set it to only between red, yellow and green and also how to control my range of colors (0-100)

import colorsys
(r, g, b) = colorsys.hsv_to_rgb(float(depth) / maxd, 1.0, 1.0)
R, G, B = int(255 * r), int(255 * g), int(255 * b)
Tak
  • 3,536
  • 11
  • 51
  • 93

2 Answers2

4

Easy. On the 0 - 1 scale that colorsys uses, the hue of red is 0 and the hue of green is 1/3, so you just need to reduce your numbers in the [0 - 100] range to the [0 - 1/3] interval by dividing.

Like this:

import colorsys

for i in range(101):
    rgb = colorsys.hsv_to_rgb(i / 300., 1.0, 1.0)
    print(i, [round(255*x) for x in rgb])

output

0 [255, 0, 0]
1 [255, 5, 0]
2 [255, 10, 0]
3 [255, 15, 0]
4 [255, 20, 0]
5 [255, 25, 0]
6 [255, 31, 0]
7 [255, 36, 0]
8 [255, 41, 0]
9 [255, 46, 0]
10 [255, 51, 0]
11 [255, 56, 0]
12 [255, 61, 0]
13 [255, 66, 0]
14 [255, 71, 0]
15 [255, 77, 0]
16 [255, 82, 0]
17 [255, 87, 0]
18 [255, 92, 0]
19 [255, 97, 0]
20 [255, 102, 0]
21 [255, 107, 0]
22 [255, 112, 0]
23 [255, 117, 0]
24 [255, 122, 0]
25 [255, 128, 0]
26 [255, 133, 0]
27 [255, 138, 0]
28 [255, 143, 0]
29 [255, 148, 0]
30 [255, 153, 0]
31 [255, 158, 0]
32 [255, 163, 0]
33 [255, 168, 0]
34 [255, 173, 0]
35 [255, 178, 0]
36 [255, 184, 0]
37 [255, 189, 0]
38 [255, 194, 0]
39 [255, 199, 0]
40 [255, 204, 0]
41 [255, 209, 0]
42 [255, 214, 0]
43 [255, 219, 0]
44 [255, 224, 0]
45 [255, 229, 0]
46 [255, 235, 0]
47 [255, 240, 0]
48 [255, 245, 0]
49 [255, 250, 0]
50 [255, 255, 0]
51 [250, 255, 0]
52 [245, 255, 0]
53 [240, 255, 0]
54 [235, 255, 0]
55 [230, 255, 0]
56 [224, 255, 0]
57 [219, 255, 0]
58 [214, 255, 0]
59 [209, 255, 0]
60 [204, 255, 0]
61 [199, 255, 0]
62 [194, 255, 0]
63 [189, 255, 0]
64 [184, 255, 0]
65 [178, 255, 0]
66 [173, 255, 0]
67 [168, 255, 0]
68 [163, 255, 0]
69 [158, 255, 0]
70 [153, 255, 0]
71 [148, 255, 0]
72 [143, 255, 0]
73 [138, 255, 0]
74 [133, 255, 0]
75 [128, 255, 0]
76 [122, 255, 0]
77 [117, 255, 0]
78 [112, 255, 0]
79 [107, 255, 0]
80 [102, 255, 0]
81 [97, 255, 0]
82 [92, 255, 0]
83 [87, 255, 0]
84 [82, 255, 0]
85 [77, 255, 0]
86 [71, 255, 0]
87 [66, 255, 0]
88 [61, 255, 0]
89 [56, 255, 0]
90 [51, 255, 0]
91 [46, 255, 0]
92 [41, 255, 0]
93 [36, 255, 0]
94 [31, 255, 0]
95 [26, 255, 0]
96 [20, 255, 0]
97 [15, 255, 0]
98 [10, 255, 0]
99 [5, 255, 0]
100 [0, 255, 0]
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • 1
    @Tak If you want to use the range [0-1] instead of [0-100] then just change the division appropriately: `rgb = colorsys.hsv_to_rgb(i / 3., 1.0, 1.0)`. Both versions handle float values of `i`. You should bear in mind that with 24 bit colour there's a maximum of 512 steps from red to green. – PM 2Ring Dec 03 '16 at 13:32
  • what if I want to switch the red and green colors? so the 100 will be red and 0 will be green? – Tak Apr 29 '17 at 05:06
  • 1
    @Tak Just subtract `i` from 100: `rgb = colorsys.hsv_to_rgb((100 - i) / 300., 1.0, 1.0)` – PM 2Ring Apr 29 '17 at 09:25
2

The HSV and HSL colorspaces allow you to choose hue independently of other parameters. If you know which contiguous range of hues you are after, you easily can map [0, 1] to that set:

def get_color(red_to_green):
    assert 0 <= red_to_green <= 1
    # in HSV, red is 0 deg and green is 120 deg (out of 360);
    # divide red_to_green with 3 to map [0, 1] to [0, 1./3.]
    hue = red_to_green / 3.0
    r, g, b = colorsys.hsv_to_rgb(hue, 1, 1)
    return map(lambda x: int(255 * x), (r, g, b))

The result is easily tested:

>>> get_color(0)
[255, 0, 0]
>>> get_color(0.2)
[255, 102, 0]
>>> get_color(0.5)
[255, 255, 0]
>>> get_color(0.7)
[153, 255, 0]
>>> get_color(1)
[0, 255, 0]
user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • So if I wanted to change my range from 0-1 to 0-100, I'll do hue = red_to_green / 300.0 instead? – Tak Dec 03 '16 at 13:30
  • @Tak Sure. In that case don't forget to update the `assert` as well. :) – user4815162342 Dec 03 '16 at 13:34
  • @Tak To prevent someone without full understanding of the API from calling e.g. `get_color(230)` and getting a garbage value. It is a good idea to "fail early" whenever possible. – user4815162342 Dec 03 '16 at 13:43