diff --git a/doc/users/next_whats_new/solarized_palette.rst b/doc/users/next_whats_new/solarized_palette.rst new file mode 100644 index 000000000000..282f2b1bca91 --- /dev/null +++ b/doc/users/next_whats_new/solarized_palette.rst @@ -0,0 +1,6 @@ +Solarized palette are now named matplotlib colors +------------------------------------------------- +Ethan Schoonover's `Solarized palette `_;. For more information on colors in matplotlib see diff --git a/examples/color/named_colors.py b/examples/color/named_colors.py index 5a16c2d813f1..bcfbcd7982ad 100644 --- a/examples/color/named_colors.py +++ b/examples/color/named_colors.py @@ -11,53 +11,77 @@ * the `matplotlib.colors` API; * the :doc:`/gallery/color/color_demo`. """ - -import matplotlib.pyplot as plt from matplotlib import colors as mcolors -colors = dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS) +# First, we define a custom plotting function that accepts a dictionary +# from one of matplotlib's named color palettes. +def plot_colors(colors, title, sort_colors=True, ncols=4): + + import matplotlib.pyplot as plt + from matplotlib.colors import rgb_to_hsv, to_rgba + + extra_rows = 2 # Additional space for title. + cell_width = 225 + cell_height = 30 + swatch_width = 50 + + # Sort colors by hue, saturation, value and name. + by_hsv = ((tuple(rgb_to_hsv(to_rgba(color)[:3])), name) + for name, color in colors.items()) + if sort_colors is True: + by_hsv = sorted(by_hsv) + names = [name for hsv, name in by_hsv] + + n = len(names) + nrows = (n + 1) // ncols + + width = cell_width * ncols + height = cell_height * (nrows + extra_rows) + dpi = 72 + fig, ax = plt.subplots(figsize=(width / dpi, height / dpi), dpi=dpi) -# Sort colors by hue, saturation, value and name. -by_hsv = sorted((tuple(mcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name) - for name, color in colors.items()) -sorted_names = [name for hsv, name in by_hsv] + ax.set_xlim(0, width) + ax.set_ylim(height, 0) + ax.yaxis.set_visible(False) + ax.xaxis.set_visible(False) + ax.set_axis_off() + ax.text(0, cell_height, title, fontsize=20) -n = len(sorted_names) -ncols = 4 -nrows = n // ncols + for i, name in enumerate(names): + row = i % nrows + col = i // nrows + y = (row + extra_rows) * cell_height -fig, ax = plt.subplots(figsize=(9, 8)) + swatch_start_x = cell_width * col + swatch_end_x = cell_width * col + swatch_width + text_pos_x = cell_width * col + swatch_width + 5 -# Get height and width -X, Y = fig.get_dpi() * fig.get_size_inches() -h = Y / (nrows + 1) -w = X / ncols + ax.text(text_pos_x, y, name, fontsize=14, + horizontalalignment='left', + verticalalignment='center') -for i, name in enumerate(sorted_names): - row = i % nrows - col = i // nrows - y = Y - (row * h) - h + ax.hlines(y, swatch_start_x, swatch_end_x, + color=colors[name], linewidth=20) - xi_line = w * (col + 0.05) - xf_line = w * (col + 0.25) - xi_text = w * (col + 0.3) + plt.show() - ax.text(xi_text, y, name, fontsize=(h * 0.5), - horizontalalignment='left', - verticalalignment='center') +# Display the 8 base colors in matplotlib. +plot_colors(mcolors.BASE_COLORS, "Base Colors", sort_colors=False, + ncols=3) - ax.hlines(y + h * 0.1, xi_line, xf_line, - color=colors[name], linewidth=(h * 0.6)) +# Displays named colors as defined by the CSS specification. +# For more on CSS colors, see https://www.w3.org/TR/css-color-4/ +plot_colors(mcolors.CSS4_COLORS, "CSS Colors") -ax.set_xlim(0, X) -ax.set_ylim(0, Y) -ax.set_axis_off() +# The Solarized palette is a 16-color palette designed for screen use. +# For more information, see https://ethanschoonover.com/solarized/ +plot_colors(mcolors.SOLARIZED_COLORS, "Solarized Palette", + sort_colors=False) -fig.subplots_adjust(left=0, right=1, - top=1, bottom=0, - hspace=0, wspace=0) -plt.show() +# This displays the classic 10-color default palette in Tableau. +plot_colors(mcolors.TABLEAU_COLORS, "Tableau Palette", sort_colors=False, + ncols=2) ############################################################################# # @@ -73,7 +97,5 @@ matplotlib.colors matplotlib.colors.rgb_to_hsv matplotlib.colors.to_rgba -matplotlib.figure.Figure.get_size_inches -matplotlib.figure.Figure.subplots_adjust matplotlib.axes.Axes.text matplotlib.axes.Axes.hlines diff --git a/lib/matplotlib/_color_data.py b/lib/matplotlib/_color_data.py index 973f4a2f2435..5a50ca71e578 100644 --- a/lib/matplotlib/_color_data.py +++ b/lib/matplotlib/_color_data.py @@ -1142,3 +1142,26 @@ 'whitesmoke': '#F5F5F5', 'yellow': '#FFFF00', 'yellowgreen': '#9ACD32'} + +# These are the 16 colors of the Solarized palette by Ethan Schoonover. +# See https://ethanschoonover.com/solarized/ +# License: https://github.com/altercation/solarized/blob/master/LICENSE +# Copyright (c) 2011 Ethan Schoonover +SOLARIZED_COLORS = { + 'solarized:base03': '#002b36', + 'solarized:base02': '#073642', + 'solarized:base01': '#586e75', + 'solarized:base00': '#657b83', + 'solarized:base0': '#839496', + 'solarized:base1': '#93a1a1', + 'solarized:base2': '#eee8d5', + 'solarized:base3': '#fdf6e3', + 'solarized:yellow': '#b58900', + 'solarized:orange': '#cb4b16', + 'solarized:red': '#dc322f', + 'solarized:magenta': '#d33682', + 'solarized:violet': '#6c71c4', + 'solarized:blue': '#268bd2', + 'solarized:cyan': '#2aa198', + 'solarized:green': '#859900', +} diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 82969ed18cb7..ad35a2c130d9 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -36,6 +36,12 @@ 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the 'T10' categorical palette (which is the default color cycle); +* one of ``{'solarized:base03', 'solarized:base02', 'solarized:base01', + 'solarized:base00', 'solarized:base0', 'solarized:base1', 'solarized:base2', + 'solarized:base3', 'solarized:yellow', 'solarized:orange', 'solarized:red', + 'solarized:magenta', 'solarized:violet', 'solarized:blue', 'solarized:cyan', + 'solarized:green'}`` which are the colors from Ethan Schoonover's + `Solarized palette `_;. * a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the indexing occurs at artist creation time and defaults to black if the @@ -50,7 +56,8 @@ import numpy as np import matplotlib.cbook as cbook -from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS +from ._color_data import (BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, + XKCD_COLORS, SOLARIZED_COLORS) class _ColorMapping(dict): @@ -69,6 +76,7 @@ def __delitem__(self, key): _colors_full_map = {} # Set by reverse priority order. +_colors_full_map.update(SOLARIZED_COLORS) _colors_full_map.update(XKCD_COLORS) _colors_full_map.update({k.replace('grey', 'gray'): v for k, v in XKCD_COLORS.items()