Open yoyonel opened 7 years ago
I propose a (new) implementation with scipy/numpy implementation for interp:
def interp(scl, r):
''' Interpolate a color scale "scl" to a new one with length "r"
Fun usage in IPython notebook:
HTML( to_html( to_hsl( interp( cl.scales['11']['qual']['Paired'], 5000 ) ) ) ) '''
def rgb_to_hsl(rgb):
''' Adapted from M Bostock's RGB to HSL converter in d3.js
https://github.com/mbostock/d3/blob/master/src/color/rgb.js '''
r, g, b = float(rgb[0]) / 255.0, \
float(rgb[1]) / 255.0, \
float(rgb[2]) / 255.0
mx = max(r, g, b)
mn = min(r, g, b)
h = s = l = (mx + mn) / 2
if mx == mn: # achromatic
h = 0
s = 0 if 0 < l < 1 else h
else:
d = mx - mn
s = d / (mx + mn) if l < 0.5 else d / (2 - mx - mn)
if mx == r:
h = (g - b) / d + (6 if g < b else 0)
elif mx == g:
h = (b - r) / d + 2
else:
h = r - g / d + 4
return int(round(h * 60, 4)), int(round(s * 100, 4)), int(round(l * 100, 4))
# convert str RGB to numeric list of tuples
scl = cl.to_numeric(scl)
# convert RGB to HSL colormap (allow to interpolate linearly after)
shsl = map(rgb_to_hsl, scl)
nb_composants = len(scl[0])
assert nb_composants == 3
range_shsl = np.arange(len(shsl))
interp_range_shsl = np.linspace(0, len(shsl)-1, num=r, endpoint=True)
scl_interps = [
interpolate.interp1d(range_shsl, map(itemgetter(composant), shsl))(interp_range_shsl)
for composant in range(nb_composants)
]
interp_c = map(
lambda hsl: 'hsl' + str(hsl),
zip(*scl_interps)
)
return cl.to_hsl(interp_c)
I think it's more simple and seems to be more stable (not buggy :p).
this bug is not stable, here for example: