%matplotlib inline
Load the script
run color_creator.py
from IPython.html.widgets import interact
lightness L lives between 0 and 100. a and b between -128 and +127 (not totally sure), using skimage.color
implementation of conversion functions.
plot_ab_plane(25)
plot_ab_plane(50)
plot_ab_plane(75)
%matplotlib inline
interact(plot_ab_plane, L=(0., 100., 2));
TODO (low priority): record an animation of L varying between 0 and 100.
http://matplotlib.org/examples/animation/basic_example_writer.html
%run color_creator.py
# Blue Green Orange L20-80
pts_lab = [
(20, 57, -77),
(40, -9, -25),
(60, -61, 59),
(80, 10, 75),
]
plot_lab_pts(pts_lab, markersize=20);
plt.title('Blue Green Orange L20-80');
pts_lab_interp = interp_lab(pts_lab, 5)
pts_lab_interp.shape
(16, 3)
plot_lab_pts(pts_lab_interp, markersize=10);
plt.title('Blue Green Orange L20-80');
cmap = cmap_from_lab_pts(pts_lab)
cmap(0.0), cmap(1.0)
((0.077676457080707972, 0.01153735488219438, 0.65379846568805156, 1.0), (0.97942192712752985, 0.73967094129870081, 0.16519518694123592, 1.0))
plot_cmap(cmap, title='Blue Green Orange L20-80')
<matplotlib.axes._subplots.AxesSubplot at 0x7f40470764d0>
plot_cmap(cmap_from_lab_pts(pts_lab, n_interp=5),
title='Blue Green Orange, with 5 interpolated pts');
For comparison: Brewer's YlGnBu
plot_cmap(mpl.cm.YlGnBu_r, title='YlGnBu (reversed)');
demo_cmap(pts_lab)
def tfun_3hills(x,y):
'''2D function on [-1,1]x[-1,1], with 3 hills of different heights,
and one wide hole
'''
def bell(x,y):
return np.exp(-(x**2+y**2))
z = 0
z -= bell(x,y)
z += bell((x-0.7)*4, y*4)
z += bell(x*4, (y-0.7)*4)*2
z += bell((x+0.7)*4, y*4)*3
return z
x = np.linspace(-1,1, 300)
plt.plot(x, tfun_3hills(x, 0));
plt.title('cut along the x axis, at y=0')
plt.xlabel('x');
pts_lab = np.array(
[[ 5. , 30.27572536, -43.70877636],
[ 28.5 , -9.58731303, -19.99279149],
[ 50. , -42.63831321, 16.08578122],
[ 67.5 , -54.49630564, 65.03153721],
[ 95. , -17.66083979, 92.27969003]])
cmap = cmap_from_lab_pts(pts_lab)
def plot_tfun(tfun, cmap, reverse=False):
y,x = np.ogrid[-1:1:100j, -1:1:100j]
z = tfun(x,y)
if reverse:
z = -z
fig, ax = plt.subplots(1,1, figsize=(5,3), num='cmap test')
im = ax.imshow(z, origin='lower', cmap=cmap, extent=[-1,1, -1, 1])
plt.colorbar(im, ax=ax)
ax.set_title('cmap test')
fig.tight_layout()
plot_tfun(tfun_3hills, cmap)
plot_tfun(tfun_3hills, cmap, reverse=True)
def plot_tfun_compare(tfun, cmap, reverse=False):
y,x = np.ogrid[-1:1:100j, -1:1:100j]
z = tfun(x,y)
if reverse:
z = -z
fig, ax = plt.subplots(2,2, figsize=(10,8))
cmaps = [[cmap, 'YlGnBu_r'],
['gray', 'jet']]
for i in [0,1]:
for j in [0,1]:
im = ax[i,j].imshow(z, origin='lower', cmap=cmaps[i][j], extent=[-1,1, -1, 1]);
plt.colorbar(im, ax=ax[i,j])
if i == 0 and j == 0:
title = 'cmap under test'
else:
title='cmap "{}"'.format(cmaps[i][j])
ax[i,j].set_title(title)
fig.tight_layout()
plot_tfun_compare(tfun_3hills, cmap)
plot_tfun_compare(tfun_3hills, cmap, reverse=True)
%matplotlib inline
pts_lab = [
[ 5., 30,-43],
[ 28.5, -5,-20],
[ 50.,-42, 18],
[ 67.5,-68, 67],
[ 95., -18, 91]]
demo_cmap(pts_lab, 'Blue Green Yellow L5-95')
%matplotlib qt
ed = LabEditor(pts_lab)
# before moving the points
ed.pts_lab
array([[ 5. , 30.27572536, -43.70877636], [ 28.5 , -9.58731303, -19.99279149], [ 50. , -42.63831321, 16.08578122], [ 67.5 , -54.49630564, 65.03153721], [ 95. , -17.66083979, 92.27969003]])
Screenshot of the point editor.
The available sRGB gamut is displayed for the point being moved (circled in black). This gamut heavily depends on L value.
# after moving the points:
ed.pts_lab
array([[ 5. , 28.76193909, -41.18579924], [ 28.5 , 51.97332853, 0.44332312], [ 50. , 75.18471797, 42.82933862], [ 67.5 , 35.57397729, 73.10506398], [ 95. , -17.40854208, 89.50441521]])
%matplotlib inline
demo_cmap(ed.pts_lab, title='cmap, after editing')
# Blue Green Orange
pts_lab = [
(20, 57, -77),
(40, -9, -25),
(60, -61, 59),
(80, 10, 75),
]
demo_cmap(pts_lab, 'Blue Green Orange L20-80')
# Blue Green Yellow
pts_lab = [
[ 10., 40,-52],
[ 30., -5,-20],
[ 50.,-42, 18],
[ 70.,-68, 67],
[ 90., -9, 87]]
demo_cmap(pts_lab, 'Blue Green Yellow L10-90')
# Blue Green Yellow L10-90, after adjustment
pts_lab = np.array([[ 10. , 36.41129032, -49.87903226],
[ 30. , 0.84677419, -29.55645161],
[ 50. , -31.33064516, 3.46774194],
[ 70. , -31.33064516, 52.58064516],
[ 90. , -8.46774194, 88.99193548]])
demo_cmap(pts_lab, 'Blue Green Yellow L10-90, curved')
# Blue Green Yellow L5-95, after a weird adjustment
pts_lab = np.array([[ 5. , 20.32258065, -10.08064516],
[ 28.5 , 11.00806452, -37.17741935],
[ 50. , -33.87096774, 6.00806452],
[ 67.5 , 17.78225806, 60.2016129 ],
[ 95. , -20.32258065, 92.37903226]])
demo_cmap(pts_lab, 'Blue Green Yellow L5-95, snake')
%run color_creator.py
# Blue Magenta Orange
pts_lab = np.array(
[[ 20. , 56.73387097, -76.12903226],
[ 50. , 77.90322581, 11.08870968],
[ 80. , 11.00806452, 79.67741935]])
demo_cmap(pts_lab, 'Blue Magenta Orange L20-80')
→ Nice looking, but notice that the interpolated purple points are saturated!
# Blue Magenta Yellow
pts_lab = [
[ 10., 36, -49],
[ 30., 56, -24],
[ 50., 77, 4],
[ 70., 38, 45],
[ 90., -9, 87]]
demo_cmap(pts_lab, 'Blue Magenta Yellow L10-90')
# Blue Magenta Yellow, after tuning
pts_lab = np.array([[ 10. , 30.48387097, -43.10483871],
[ 30. , 55.88709677, -13.46774194],
[ 50. , 74.51612903, 30.56451613],
[ 70. , 34.71774194, 60.2016129 ],
[ 90. , -9.31451613, 79.67741935]])
demo_cmap(pts_lab, 'Purple Red Yellow L10-90')
# Blue Magenta Yellow, L5-95
pts_lab = np.array([[ 5. , 28.76193909, -41.18579924],
[ 28.5 , 51.97332853, 0.44332312],
[ 50. , 75.18471797, 42.82933862],
[ 67.5 , 35.57397729, 73.10506398],
[ 95. , -17.40854208, 89.50441521]])
demo_cmap(pts_lab, 'Purple Red Yellow L5-95')