forked from huyaoyu/ImageFlow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathColorMapping.py
121 lines (97 loc) · 3.64 KB
/
ColorMapping.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from __future__ import print_function
# Most of the content of this file is copied from
# https://bsou.io/posts/color-gradients-with-python
from numpy import random as rnd
import numpy as np
def hex_to_RGB(hex):
''' "#FFFFFF" -> [255,255,255] '''
# Pass 16 to the integer function for change of base
return [int(hex[i:i+2], 16) for i in range(1,6,2)]
def RGB_to_hex(RGB):
''' [255,255,255] -> "#FFFFFF" '''
# Components need to be integers for hex to make sense
RGB = [int(x) for x in RGB]
return "#"+"".join(["0{0:x}".format(v) if v < 16 else
"{0:x}".format(v) for v in RGB])
def color_dict(gradient):
''' Takes in a list of RGB sub-lists and returns dictionary of
colors in RGB and hex form for use in a graphing function
defined later on '''
return {"hex":[RGB_to_hex(RGB) for RGB in gradient],
"r":[RGB[0] for RGB in gradient],
"g":[RGB[1] for RGB in gradient],
"b":[RGB[2] for RGB in gradient]}
def linear_gradient(start_hex, finish_hex="#FFFFFF", n=10):
''' returns a gradient list of (n) colors between
two hex colors. start_hex and finish_hex
should be the full six-digit color string,
inlcuding the number sign ("#FFFFFF") '''
# Starting and ending colors in RGB form
s = hex_to_RGB(start_hex)
f = hex_to_RGB(finish_hex)
# Initilize a list of the output colors with the starting color
RGB_list = [s]
# Calcuate a color at each evenly spaced value of t from 1 to n
for t in range(1, n):
# Interpolate RGB vector for color at the current value of t
curr_vector = [
int(s[j] + (float(t)/(n-1))*(f[j]-s[j]))
for j in range(3)
]
# Add it to our list of output colors
RGB_list.append(curr_vector)
return color_dict(RGB_list)
def rand_hex_color(num=1):
''' Generate random hex colors, default is one,
returning a string. If num is greater than
1, an array of strings is returned. '''
colors = [
RGB_to_hex([x*255 for x in rnd.rand(3)])
for i in range(num)
]
if num == 1:
return colors[0]
else:
return colors
def polylinear_gradient(colors, n):
''' returns a list of colors forming linear gradients between
all sequential pairs of colors. "n" specifies the total
number of desired output colors '''
# The number of colors per individual linear gradient
n_out = int(float(n) / (len(colors) - 1))
# returns dictionary defined by color_dict()
gradient_dict = linear_gradient(colors[0], colors[1], n_out)
if len(colors) > 1:
for col in range(1, len(colors) - 1):
next = linear_gradient(colors[col], colors[col+1], n_out)
for k in ("hex", "r", "g", "b"):
# Exclude first point to avoid duplicates
gradient_dict[k] += next[k][1:]
return gradient_dict
def color_map(data, colors, nLevels):
# Get the color gradient dict.
gradientDict = polylinear_gradient(colors, nLevels)
# Get the actual levels generated.
n = len( gradientDict["hex"] )
# Level step.
dMin = data.min()
dMax = data.max()
step = ( dMax - dMin ) / (n-1)
stepIdx = ( data - dMin ) / step
stepIdx = stepIdx.astype(np.int)
rArray = np.array( gradientDict["r"] )
gArray = np.array( gradientDict["g"] )
bArray = np.array( gradientDict["b"] )
r = rArray[ stepIdx ]
g = gArray[ stepIdx ]
b = bArray[ stepIdx ]
return r, g, b
if __name__ == "__main__":
colors = [\
"#2980b9",\
"#27ae60",\
"#f39c12",\
"#c0392b",\
]
data = np.linspace(0, 99, 100)
r, g, b = color_map(data, colors, 20)