Skip to content

Instantly share code, notes, and snippets.

@ihincks
Last active August 30, 2023 21:49
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ihincks/6a420b599f43fcd7dbd79d56798c4e5a to your computer and use it in GitHub Desktop.
Save ihincks/6a420b599f43fcd7dbd79d56798c4e5a to your computer and use it in GitHub Desktop.
Function to lighten any color in matplotlib
def lighten_color(color, amount=0.5):
"""
Lightens the given color by multiplying (1-luminosity) by the given amount.
Input can be matplotlib color string, hex string, or RGB tuple.
Examples:
>> lighten_color('g', 0.3)
>> lighten_color('#F034A3', 0.6)
>> lighten_color((.3,.55,.1), 0.5)
"""
import matplotlib.colors as mc
import colorsys
try:
c = mc.cnames[color]
except:
c = color
c = np.array(colorsys.rgb_to_hls(*mc.to_rgb(c)))
return colorsys.hls_to_rgb(c[0],1-amount * (1-c[1]),c[2])
@Splines
Copy link

Splines commented Feb 24, 2022

This is great, thank you 👍 Love that you also included docstrings with examples.

Note that if you want to get back a hex value, you can do:

c = np.array(colorsys.rgb_to_hls(*mc.to_rgb(c)))
hls = (c[0], 1 - amount*(1-c[1]), c[2])
rgb = colorsys.hls_to_rgb(*hls)
return mc.to_hex(rgb)

I've also adjusted spacing and added an optional paranthesis to make visually clear that we don't multiply 1-amount by 1-c[1] but rather do 1 minus amount*(1-c[1]).

@Splines
Copy link

Splines commented Feb 24, 2022

Also note that F Lekschas proposed a very good adaption on StackOverflow (edit 3):

c = np.array(colorsys.rgb_to_hls(*mc.to_rgb(c)))
hls = (c[0], max(0, min(1, amount * c[1])), c[2])
rgb = colorsys.hls_to_rgb(*hls)
return mc.to_hex(rgb)

such that the color gets brighter when amount > 1 and darker when amount < 1. I also restricted the luminosity to [0,1] as values outside don't make sense. ~ F Lekschas

@Oakchris1955
Copy link

Made a version of it that takes RGB values from 0-255

def adjust_lightness(input_color, amount):
	color = (input_color[0]/255, input_color[1]/255, input_color[2]/255)
	try:
		c = mc.cnames[color]
	except:
		c = color
	c = colorsys.rgb_to_hls(*mc.to_rgb(c))
	float_color = colorsys.hls_to_rgb(c[0], max(0, min(1, amount * c[1])), c[2])
	return list(round(i*255) for i in float_color)

Found this Gist thanks to this StackOverflow link

@nitish1295
Copy link

nitish1295 commented May 8, 2022

In case you need to new custom LinearSegmentedColormap like I did. The original Stackoverflow Question

def custom_cmap_lightness(color, under=0.8, over=1.3):
    color_ligten = []
    
    for amount in np.linspace(under,over,1000):
        
        try:
            c = mc.cnames[color]
        except:
            c = color
        c = colorsys.rgb_to_hls(*mc.to_rgb(c))
        new_color = colorsys.hls_to_rgb(c[0], max(0, min(1, amount * c[1])), c[2])
        color_ligten.append(new_color)
        
    color_ligten.reverse()
    new_cmp = LinearSegmentedColormap.from_list('testCmap', colors=color_ligten, N=256)
    return new_cmp

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment