diff --git a/doc/users/colors.rst b/doc/users/colors.rst
index 18a5756f0ab5..d08861bccec0 100644
--- a/doc/users/colors.rst
+++ b/doc/users/colors.rst
@@ -17,6 +17,10 @@ it can be provided as:
* a name from the `xkcd color survey `__
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``)
* one of ``{'C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9'}``
+* one of ``{'tab:blue', 'tab:orange', 'tab:green',
+ '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).
All string specifications of color are case-insensitive.
diff --git a/doc/users/dflt_style_changes.rst b/doc/users/dflt_style_changes.rst
index 125a95892f7e..34aaddaf02c5 100644
--- a/doc/users/dflt_style_changes.rst
+++ b/doc/users/dflt_style_changes.rst
@@ -32,8 +32,13 @@ Colors in default property cycle
--------------------------------
The colors in the default property cycle have been changed from
-``['b', 'g', 'r', 'c', 'm', 'y', 'k']`` to the `Vega category10 palette
-`__
+``['b', 'g', 'r', 'c', 'm', 'y', 'k']`` to the category10
+color palette used by `Vega
+`__ and
+`d3
+`__
+originally developed at Tableau.
+
.. plot::
diff --git a/lib/matplotlib/_color_data.py b/lib/matplotlib/_color_data.py
index 11a538f34722..7c47eca30378 100644
--- a/lib/matplotlib/_color_data.py
+++ b/lib/matplotlib/_color_data.py
@@ -1,6 +1,6 @@
from __future__ import (absolute_import, division, print_function,
unicode_literals)
-
+from collections import OrderedDict
import six
@@ -15,6 +15,24 @@
'w': (1, 1, 1)}
+# These colors are from Tableau
+TABLEAU_COLORS = OrderedDict((
+ ('blue', '#1f77b4'),
+ ('orange', '#ff7f0e'),
+ ('green', '#2ca02c'),
+ ('red', '#d62728'),
+ ('purple', '#9467bd'),
+ ('brown', '#8c564b'),
+ ('pink', '#e377c2'),
+ ('gray', '#7f7f7f'),
+ ('olive', '#bcbd22'),
+ ('cyan', '#17becf'))
+)
+
+# Normalize name to "tab:" to avoid name collisions.
+TABLEAU_COLORS = OrderedDict(
+ ('tab:' + name, value) for name, value in TABLEAU_COLORS.items())
+
# This mapping of color names -> hex values is taken from
# a survey run by Randel Monroe see:
# http://blog.xkcd.com/2010/05/03/color-survey-results/
@@ -973,7 +991,6 @@
'green': '#15b01a',
'purple': '#7e1e9c'}
-
# Normalize name to "xkcd:" to avoid name collisions.
XKCD_COLORS = {'xkcd:' + name: value for name, value in XKCD_COLORS.items()}
diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py
index 2825c33fe97f..ee1b41e17757 100644
--- a/lib/matplotlib/colors.py
+++ b/lib/matplotlib/colors.py
@@ -66,7 +66,7 @@
import numpy as np
from numpy import ma
import matplotlib.cbook as cbook
-from ._color_data import BASE_COLORS, CSS4_COLORS, XKCD_COLORS
+from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS
class _ColorMapping(dict):
@@ -86,7 +86,14 @@ def __delitem__(self, key, value):
_colors_full_map = {}
# Set by reverse priority order.
_colors_full_map.update(XKCD_COLORS)
+_colors_full_map.update({k.replace('grey', 'gray'): v
+ for k, v in XKCD_COLORS.items()
+ if 'grey' in k})
_colors_full_map.update(CSS4_COLORS)
+_colors_full_map.update(TABLEAU_COLORS)
+_colors_full_map.update({k.replace('gray', 'grey'): v
+ for k, v in TABLEAU_COLORS.items()
+ if 'gray' in k})
_colors_full_map.update(BASE_COLORS)
_colors_full_map = _ColorMapping(_colors_full_map)
@@ -253,7 +260,7 @@ def to_hex(c, keep_alpha=False):
### Backwards-compatible color-conversion API
cnames = CSS4_COLORS
-COLOR_NAMES = {'xkcd': XKCD_COLORS, 'css4': CSS4_COLORS}
+COLOR_NAMES = {'xkcd': XKCD_COLORS, 'css4': CSS4_COLORS, 'tc': TABLEAU_COLORS}
hexColorPattern = re.compile("\A#[a-fA-F0-9]{6}\Z")
@@ -404,7 +411,7 @@ class Colormap(object):
"""
def __init__(self, name, N=256):
- r"""
+ """
Parameters
----------
name : str
diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py
index 4f9c44c16ccf..233616ccb65e 100644
--- a/lib/matplotlib/tests/test_colors.py
+++ b/lib/matplotlib/tests/test_colors.py
@@ -571,9 +571,10 @@ def angled_plane(azimuth, elevation, angle, x, y):
assert_array_almost_equal(h, np.cos(np.radians(angle)))
-def test_xkcd():
+def test_color_names():
assert mcolors.to_hex("blue") == "#0000ff"
assert mcolors.to_hex("xkcd:blue") == "#0343df"
+ assert mcolors.to_hex("tab:blue") == "#1f77b4"
def _sph2cart(theta, phi):
@@ -643,6 +644,23 @@ def test_conversions():
hex_color)
+def test_grey_gray():
+ color_mapping = mcolors._colors_full_map
+ for k in color_mapping.keys():
+ if 'grey' in k:
+ assert color_mapping[k] == color_mapping[k.replace('grey', 'gray')]
+ if 'gray' in k:
+ assert color_mapping[k] == color_mapping[k.replace('gray', 'grey')]
+
+
+def test_tableau_order():
+ dflt_cycle = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728',
+ '#9467bd', '#8c564b', '#e377c2', '#7f7f7f',
+ '#bcbd22', '#17becf']
+
+ assert list(mcolors.TABLEAU_COLORS.values()) == dflt_cycle
+
+
if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)