proplot
proplot copied to clipboard
Perceptually uniform cyclic colormaps
We are considering packing proplot with some custom cyclic colormaps. Below is an example that I'm toying with.
@bradyrx It turns out that luminance + chroma as sine curves in quadrature give you uniform, colorblind-friendly single hue maps! I tried making a cyclic multihue map this way but it turns out to be way harder. HSL and HPL give weird zig-zags in chroma/luminance and in HCL, it's almost impossible to "thread the needle" between valid values (i.e. values that translate to non-impossible RGB colors).
Feel free to play with this example:
import proplot as plot
import numpy as np
space = 'hcl'
hue = 'medium blue'
reverse = False
luminance_shift = 0
saturation_shift = np.pi/2
luminance_offset = 0
saturation_offset = 0
luminance_scale = 80
saturation_scale = 60
luminance = lambda x: luminance_offset + 50 + luminance_scale*np.sin(x*2*np.pi + luminance_shift)/2
saturation = lambda x: saturation_offset + 50 + saturation_scale*np.sin(x*2*np.pi + saturation_shift)/2
cmap = plot.PerceptuallyUniformColormap.from_hsl('_cyclic',
# hue=(hue, hue + 360)[::1 - 2*reverse], # cyclic hues!
hue=hue, # constant hue!
saturation=saturation, luminance=luminance,
cyclic=True, space=space)
cmap = cmap.shifted(180) # optionally shift
f = plot.show_channels(cmap, rgb=False, axwidth=1.5)
f, ax = plot.subplots()
ax.pcolormesh(np.ones((30,30)).cumsum(axis=0) % 10, cmap=cmap, colorbar='b')
ax.format(suptitle='Cyclic colormap test')
Here's a red one.
space = 'hcl'
hue = 'brick red'
Throwing in some hue wiggles makes it a bit more interesting (might use something close to this one!).
import proplot as plot
import numpy as np
space = 'hcl'
hue = 'brick red'
reverse = False
luminance_shift = 0
saturation_shift = np.pi/2
hue_offset = 20
luminance_offset = 0
saturation_offset = 0
hue_scale = 50
luminance_scale = 60
saturation_scale = 60
hue = lambda x: hue_offset + hue_scale*np.sin(x*2*np.pi)/2
luminance = lambda x: luminance_offset + 50 + luminance_scale*np.sin(x*2*np.pi + luminance_shift)/2
saturation = lambda x: saturation_offset + 50 + saturation_scale*np.sin(x*2*np.pi + saturation_shift)/2
cmap = plot.PerceptuallyUniformColormap.from_hsl('_cyclic',
# hue=(hue, hue + 360)[::1 - 2*reverse], # cyclic hues!
hue=hue, # constant hue!
saturation=saturation, luminance=luminance,
cyclic=True, space=space)
cmap = cmap.shifted(180) # optionally shift
f = plot.show_channels(cmap, rgb=False, axwidth=1.5)
f, ax = plot.subplots()
ax.pcolormesh(np.ones((30,30)).cumsum(axis=0) % 10, cmap=cmap, colorbar='b')
ax.format(suptitle='Cyclic colormap test')
This looks great! @jessica-tomaszewski