Say I have a color in Matplotlib. Maybe it's a string ('k'
) or an rgb tuple ((0.5, 0.1, 0.8)
) or even some hex (#05FA2B
). Is there a command / convenience function in Matplotlib that would allow me to darken (or lighten) that color.
I.e. is there matplotlib.pyplot.darken(c, 0.1)
or something like that? I guess what I'm hoping for is something that, behind the scenes, would take a color, convert it to HSL, then either multiply the L value by some given factor (flooring at 0 and capping at 1) or explicitly set the L value to a given value and return the modified color.
set_hls_values() takes a color as RGB-Tuple, HEX or HTML-name and lets you manipulate the hue, lightness and saturation. The scaled lightness should be between 0 and 1 , where 1 < scale increases the lightness and 0 ≤ scale < 1 darkens the color.
For shades, multiply each component by 1/4, 1/2, 3/4, etc., of its previous value. The smaller the factor, the darker the shade. For tints, calculate (255 - previous value), multiply that by 1/4, 1/2, 3/4, etc.
You can use ax. axvspan , which apparently does exactely what you want. For better results, usa an alpha value below 0.5, and optionally set color and edge-color/width. If you want the shading to be in a different orientation (horizontal instead of vertical), there is also the ax.
Here is a function from my gist to lighten any color that I think will work with any color format known to matplotlib
. I think setting an amount > 1 might darken too.
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 = colorsys.rgb_to_hls(*mc.to_rgb(c)) return colorsys.hls_to_rgb(c[0], 1 - amount * (1 - c[1]), c[2])
EDIT: Indeed, it does darken as well as lighten:
import matplotlib.pyplot as plt import numpy as np xs = np.linspace(-1, 1, 100) plt.plot(xs, 0 * xs, color='b', lw=3) plt.plot(xs, xs**2, color=lighten_color('b', 0.4), lw=3) plt.plot(xs, -xs**2, color=lighten_color('b', 1.6), lw=3)
Edit 2: Removed un-needed numpy dependency in the function.
Edit 3: Function modified with improvements from @FLekschas
def adjust_lightness(color, amount=0.5): import matplotlib.colors as mc import colorsys try: c = mc.cnames[color] except: c = color c = colorsys.rgb_to_hls(*mc.to_rgb(c)) return colorsys.hls_to_rgb(c[0], max(0, min(1, amount * c[1])), c[2])
Using only colorsys which is part of the python standard library it is possible to scale the lighntess with just two lines of code
If you still want the option to pass non rgb values like colornames or HEX you can simply use matplotlib.colors.ColorConverter.to_rgb("#ff0000")
.
This method scales the lightness of an rgb color
import colorsys def scale_lightness(rgb, scale_l): # convert rgb to hls h, l, s = colorsys.rgb_to_hls(*rgb) # manipulate h, l, s values and return as rgb return colorsys.hls_to_rgb(h, min(1, l * scale_l), s = s)
A simple demonstration. For more details have a look at the old example.
import matplotlib import seaborn as sns color = matplotlib.colors.ColorConverter.to_rgb("navy") rgbs = [scale_lightness(color, scale) for scale in [0, .5, 1, 1.5, 2]] sns.palplot(rgbs)
There is a Seaborn method, that easily lets you manipulate the lightness. seaborn.set_hls_values()
takes a color as RGB-Tuple, HEX or HTML-name and lets you manipulate the hue, lightness and saturation.
The scaled lightness should be between 0
and 1
, where 1 < scale
increases the lightness and 0 ≤ scale < 1
darkens the color.
from colorsys import rgb_to_hls import seaborn as sns color = (1.0, 0.0, 0.0) # RGB print(f"Input color: \t Lightness: {rgb_to_hls(*color)[1]: .2g}\t RGB: {color}") rgbs = [] for scale in [0, .5, 1, 1.5, 2]: # scale the lightness (The values should be between 0 and 1) lightness = min(1, rgb_to_hls(*color)[1] * scale) # manipulate h, l, s channel of a rgb color rgb = sns.set_hls_values(color = color, h = None, l = lightness, s = None) print(f"Scale factor: {scale: .2g}\t Lightness: {lightness: .2g} \t RGB: {rgb}") rgbs.append(rgb) sns.palplot(rgbs)
In case you want to use other than RGB codes you need to convert your color to RGB. You could use the following command.
color = "red" # HTML name color = "#ff0000" # HEX color = matplotlib.colors.ColorConverter.to_rgb(color)
The returned values are RGB-Tuples:
Input color: Lightness: 0.5 RGB: (1.0, 0.0, 0.0) Scale factor: 0 Lightness: 0 RGB: (0.0, 0.0, 0.0) # Black Scale factor: 0.5 Lightness: 0.25 RGB: (0.5, 0.0, 0.0) Scale factor: 1 Lightness: 0.5 RGB: (1.0, 0.0, 0.0) # Unchanged Scale factor: 1.5 Lightness: 0.75 RGB: (1.0, 0.5, 0.5) Scale factor: 2 Lightness: 1 RGB: (1.0, 1.0, 1.0) # White
Thanks @fhgd! I changed the code to actually scale the lightness and not just set it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With