From b0d9da31de482db42e19f4053de82c87efc0f6fd Mon Sep 17 00:00:00 2001 From: David Reed Date: Sun, 19 Jan 2014 12:22:42 -0500 Subject: [PATCH 1/4] NF - added new feature to colors called shade_color to lighten or darken a given color by a given percentage --- lib/matplotlib/colors.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 5d2cbb3bd463..57bf1191024b 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -67,6 +67,7 @@ import numpy as np import matplotlib.cbook as cbook +from colorsys import rgb_to_hls as rgb2hls, hls_to_rgb as hls2rgb from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS @@ -1947,3 +1948,38 @@ def from_levels_and_colors(levels, colors, extend='neither'): norm = BoundaryNorm(levels, ncolors=n_data_colors) return cmap, norm + +def shade_color(color, percent): + """Shade Color + + This color utility function allows the user to easily darken or lighten a color for + plotting purposes. + + Parameters + ---------- + color : string, list, hexvalue + Any acceptable Matplotlib color value, such as 'red', 'slategrey', '#FFEE11', (1,0,0) + + percent : the amount by which to brighten or darken the color. + + Returns + ------- + color : tuple of floats + tuple representing converted rgb values + + """ + + cc = CC() + + rgb = cc.to_rgb(color) + + h,l,s = rgb2hls(*rgb) + + l *= 1 + float(percent)/100 + + l = min(1, l) + l = max(0, l) + + r,g,b = hls2rgb(h,l,s) + + return r,g,b From a9bc899ad522bcec376444eabc6647ccefdf6fbc Mon Sep 17 00:00:00 2001 From: David Reed Date: Sun, 19 Jan 2014 12:33:27 -0500 Subject: [PATCH 2/4] NF - added new feature to colors called shade_color to lighten or darken a given color by a given percentage (altered CC to ColorConverter) --- lib/matplotlib/colors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 57bf1191024b..75748933a0ac 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -1969,7 +1969,7 @@ def shade_color(color, percent): """ - cc = CC() + cc = ColorConverter() rgb = cc.to_rgb(color) From 8ada83e7a2201d2a1eba0785a301edb85e849711 Mon Sep 17 00:00:00 2001 From: David Reed Date: Sat, 16 May 2015 12:11:35 -0400 Subject: [PATCH 3/4] NF - added new feature to colors called shade_color to lighten or darken a given color by a given percentage, added modifications noted in PR #2745 which included fixing PEP8 errors and adding a test. --- lib/matplotlib/colors.py | 32 +++++++++++++++-------------- lib/matplotlib/tests/test_colors.py | 30 ++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 75748933a0ac..bb075788d4af 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -64,10 +64,12 @@ from collections import Sized import re import warnings +from colorsys import rgb_to_hls, hls_to_rgb + import numpy as np import matplotlib.cbook as cbook -from colorsys import rgb_to_hls as rgb2hls, hls_to_rgb as hls2rgb + from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS @@ -1949,18 +1951,23 @@ def from_levels_and_colors(levels, colors, extend='neither'): norm = BoundaryNorm(levels, ncolors=n_data_colors) return cmap, norm + def shade_color(color, percent): - """Shade Color + """A color helper utility to either darken or lighten given color. - This color utility function allows the user to easily darken or lighten a color for - plotting purposes. + This color utility function allows the user to easily darken or + lighten a color for plotting purposes. This function first + converts the given color to RGB using ColorConverter and then to + HSL. The saturation is modified according to the given percentage + and converted back to RGB. Parameters ---------- color : string, list, hexvalue - Any acceptable Matplotlib color value, such as 'red', 'slategrey', '#FFEE11', (1,0,0) + Any acceptable Matplotlib color value, such as 'red', + 'slategrey', '#FFEE11', (1,0,0) - percent : the amount by which to brighten or darken the color. + percent : the amount by which to brighten or darken the color. Returns ------- @@ -1969,17 +1976,12 @@ def shade_color(color, percent): """ - cc = ColorConverter() + rgb = colorConverter.to_rgb(color) - rgb = cc.to_rgb(color) - - h,l,s = rgb2hls(*rgb) + h, l, s = rgb_to_hls(*rgb) l *= 1 + float(percent)/100 - l = min(1, l) - l = max(0, l) - - r,g,b = hls2rgb(h,l,s) + l = np.clip(l, 0, 1) - return r,g,b + return hls_to_rgb(h, l, s) diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index 20f80755c2cb..ea3620ab2606 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -10,7 +10,8 @@ import numpy as np import pytest -from numpy.testing.utils import assert_array_equal, assert_array_almost_equal +from numpy.testing.utils import (assert_array_equal, + assert_array_almost_equal, assert_equal) from matplotlib import cycler import matplotlib @@ -708,3 +709,30 @@ def __add__(self, other): mcolors.SymLogNorm(3, vmax=5, linscale=1), mcolors.PowerNorm(1)]: assert_array_equal(norm(data.view(MyArray)), norm(data)) + + +def _shade_test_helper(color, shade, expected): + sc = mcolors.shade_color(color, shade) + assert_equal(sc, expected) + + +def test_color_shading(): + test_colors = ( + 'white', + 'red', + 'black', + [0, .5, .9], + 'slategrey', + ) + test_shade = (0, .5, 1, -.5, -1) + known_shaded_result = ( + (1.0, 1.0, 1.0), + (1.0, 0.0049999999999998934, 0.0049999999999998934), + (0.0, 0.0, 0.0), + (0.0, 0.49749999999999983, 0.89549999999999996), + (0.43433441408059281, 0.49694117647058816, 0.55954793886058363) + ) + for color, shade, expected in zip(test_colors, + test_shade, + known_shaded_result): + _shade_test_helper(color, shade, expected) From e5957e15692101afda27cca08127e9ee127d2c0b Mon Sep 17 00:00:00 2001 From: David Reed Date: Sat, 16 May 2015 12:40:50 -0400 Subject: [PATCH 4/4] NF - added new feature to colors called shade_color to lighten or darken a given color by a given percentage, added modifications noted in PR #2745 which included fixing PEP8 errors and adding a test. --- doc/users/whats_new/2015-05_color_shading.rst | 9 ++++++++ examples/color/color_shade_demo.py | 21 +++++++++++++++++++ lib/matplotlib/tests/test_colors.py | 16 ++++++++------ 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 doc/users/whats_new/2015-05_color_shading.rst create mode 100644 examples/color/color_shade_demo.py diff --git a/doc/users/whats_new/2015-05_color_shading.rst b/doc/users/whats_new/2015-05_color_shading.rst new file mode 100644 index 000000000000..264976cdd1c6 --- /dev/null +++ b/doc/users/whats_new/2015-05_color_shading.rst @@ -0,0 +1,9 @@ +Easy color shading +`````````````````` +Often we would like the ability add subtle color variation to our plots, +especially when similar element are plotted in close proximity to one another. +:func:`matplotlib.colors.shade_color` can be used to take an existing color and +slightly darken it, by giving a negative percentage, or to slightly lighten it, +by giving a positive percentage. + +.. plot:: mpl_examples/color/color_shade_demo.py diff --git a/examples/color/color_shade_demo.py b/examples/color/color_shade_demo.py new file mode 100644 index 000000000000..39b278d4f325 --- /dev/null +++ b/examples/color/color_shade_demo.py @@ -0,0 +1,21 @@ +""" +Demo of shade_color utility. + +""" +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors + +fig = plt.figure() +ax = fig.add_subplot(111) + +lightened_color = mcolors.shade_color('blue', -50) +darkened_color = mcolors.shade_color('blue', +50) + +ax.fill_between([0,1], [0,0], [1,1], facecolor=darkened_color) +ax.fill_between([0,1], [0,0], [.66, .66], facecolor='blue') +ax.fill_between([0,1], [0,0], [.33, .33], facecolor=lightened_color) + +plt.xlim([0, 1]) +plt.ylim([0, 1]) + +plt.show() \ No newline at end of file diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py index ea3620ab2606..2db268b494c7 100644 --- a/lib/matplotlib/tests/test_colors.py +++ b/lib/matplotlib/tests/test_colors.py @@ -718,19 +718,23 @@ def _shade_test_helper(color, shade, expected): def test_color_shading(): test_colors = ( - 'white', 'red', - 'black', + 'red', + 'red', + 'red', + 'red', [0, .5, .9], 'slategrey', ) - test_shade = (0, .5, 1, -.5, -1) + test_shade = (0, 50, 100, -50, -100, 20, -20) known_shaded_result = ( + (1.0, 0.0, 0.0), + (1.0, 0.5, 0.5), (1.0, 1.0, 1.0), - (1.0, 0.0049999999999998934, 0.0049999999999998934), + (0.5, 0.0, 0.0), (0.0, 0.0, 0.0), - (0.0, 0.49749999999999983, 0.89549999999999996), - (0.43433441408059281, 0.49694117647058816, 0.55954793886058363) + (0.080000000000000071, 0.59111111111111092, 1.0), + (0.35097730430754981, 0.40156862745098038, 0.45215995059441105) ) for color, shade, expected in zip(test_colors, test_shade,