Skip to content

Perceptually uniform cyclic colormaps #70

Open

Description

@lukelbd

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')

image

image

Activity

  1. lukelbd commented on Nov 27, 2019

    @lukelbd
    CollaboratorAuthor

    Here's a red one.

    space = 'hcl'
    hue = 'brick red'

    image

    image

  2. lukelbd commented on Nov 27, 2019

    @lukelbd
    CollaboratorAuthor

    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')

    image

    image

  3. bradyrx commented on Dec 2, 2019

    @bradyrx
    Collaborator

    This looks great! @jessica-tomaszewski

  4. added this to the Version 0.10 milestone on Jul 21, 2021
  5. removed this from the Version 0.10 milestone on Jan 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions