8000 Introduce new Tableau colors · matplotlib/matplotlib@3220bb2 · GitHub
[go: up one dir, main page]

Skip to content
Sign in

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3220bb2

Browse files
Introduce new Tableau colors
1 parent f38a600 commit 3220bb2

File tree

9 files changed

+212
-69
lines changed

9 files changed

+212
-69
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
:orphan:
2+
3+
Introduce new Tableau colors
4+
----------------------------
5+
6+
In its version 10, Tableau `introduced a new palette of categorical colors
7+
<https://www.tableau.com/about/blog/2016/7/colors-upgrade-tableau-10-56782>`__.
8+
Those are now available in matplotlib with the prefix ``tabx:``:
9+
``{'tabx:blue', 'tabx:orange', 'tabx:red', 'tabx:cyan', 'tabx:green',
10+
'tabx:yellow', 'tabx:purple', 'tabx:pink', 'tabx:brown', 'tabx:grey'}``
11+
12+
Those colors are also provided as a new ``tabx10`` colormap. An additional
13+
``tabx20`` colormap with is added.
14+
15+
In general those colors are a little less saturated than those from the default
16+
color cycle. Replacing the default color cycler with those colors can e.g. be
17+
achieved via
18+
19+
::
20+
21+
cols = plt.cm.tabx10.colors
22+
plt.rcParams["axes.prop_cycle"] = plt.cycler("color", cols)}
23+
24+

examples/color/color_demo.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Color Demo
44
==========
55
6-
Matplotlib gives you 8 ways to specify colors,
6+
Matplotlib gives you 7 ways to specify colors,
77
88
1) an RGB or RGBA tuple of float values in ``[0, 1]`` (e.g. ``(0.1, 0.2, 0.5)``
99
or ``(0.1, 0.2, 0.5, 0.3)``). RGBA is short for Red, Green, Blue, Alpha;
@@ -13,16 +13,25 @@
1313
4) a single letter string, i.e. one of
1414
``{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}``;
1515
5) a X11/CSS4 ("html") color name, e.g. ``"blue"``;
16-
6) a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__,
17-
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
16+
6) a color name from a palette, prefixed with the palette's name:
17+
18+
a. a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__;
19+
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
20+
b. one of ``{'tab:blue', 'tab:orange', 'tab:green',
21+
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
22+
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from
23+
the 'T10' categorical palette (which is the default color cycle);
24+
c. one of ``{'tabx:blue', 'tabx:orange', 'tabx:red', 'tabx:cyan',
25+
'tabx:green', 'tabx:yellow', 'tabx:purple', 'tabx:pink', 'tabx:brown',
26+
'tabx:gray' }`` which are the colors from the
27+
`new Tableau10 categorical palette
28+
<https://www.tableau.com/about/blog/2016/7/colors-upgrade-tableau-10-\
29+
56782>`__;
30+
1831
7) a "Cn" color spec, i.e. `'C'` followed by a single digit, which is an index
1932
into the default property cycle
2033
(``matplotlib.rcParams['axes.prop_cycle']``); the indexing occurs at artist
2134
creation time and defaults to black if the cycle does not include color.
22-
8) one of ``{'tab:blue', 'tab:orange', 'tab:green',
23-
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
24-
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
25-
'tab10' categorical palette (which is the default color cycle);
2635
2736
For more information on colors in matplotlib see
2837
@@ -47,12 +56,14 @@
4756
ax.set_xlabel('time (s)', color='c')
4857
# 5) a named color:
4958
ax.set_ylabel('voltage (mV)', color='peachpuff')
50-
# 6) a named xkcd color:
59+
# 6a) a named xkcd color:
5160
ax.plot(t, s, 'xkcd:crimson')
61+
# 6b) tab notation:
62+
ax.tick_params(axis="x", labelcolor='tab:orange')
63+
# 6c) tabx notation:
64+
ax.tick_params(axis="y", labelcolor='tabx:yellow')
5265
# 7) Cn notation:
5366
ax.plot(t, .7*s, color='C4', linestyle='--')
54-
# 8) tab notation:
55-
ax.tick_params(labelcolor='tab:orange')
5667

5768

5869
plt.show()

examples/color/colormap_reference.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
('Qualitative', [
3434
'Pastel1', 'Pastel2', 'Paired', 'Accent',
3535
'Dark2', 'Set1', 'Set2', 'Set3',
36-
'tab10', 'tab20', 'tab20b', 'tab20c']),
36+
'tab10', 'tab20', 'tab20b', 'tab20c', 'tabx10', 'tabx20']),
3737
('Miscellaneous', [
3838
'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
3939
'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',

examples/color/named_colors.py

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,70 @@
1212
* the :doc:`/gallery/color/color_demo`.
1313
"""
1414

15-
import matplotlib.pyplot as plt
16-
from matplotlib import colors as mcolors
17-
18-
19-
colors = dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS)
20-
21-
# Sort colors by hue, saturation, value and name.
22-
by_hsv = sorted((tuple(mcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name)
23-
for name, color in colors.items())
24-
sorted_names = [name for hsv, name in by_hsv]
25-
26-
n = len(sorted_names)
27-
ncols = 4
28-
nrows = n // ncols
29-
30-
fig, ax = plt.subplots(figsize=(9, 8))
3115

32-
# Get height and width
33-
X, Y = fig.get_dpi() * fig.get_size_inches()
34-
h = Y / (nrows + 1)
35-
w = X / ncols
36-
37-
for i, name in enumerate(sorted_names):
38-
row = i % nrows
39-
col = i // nrows
40-
y = Y - (row * h) - h
41-
42-
xi_line = w * (col + 0.05)
43-
xf_line = w * (col + 0.25)
44-
xi_text = w * (col + 0.3)
45-
46-
ax.text(xi_text, y, name, fontsize=(h * 0.5),
47-
horizontalalignment='left',
48-
verticalalignment='center')
49-
50-
ax.hlines(y + h * 0.1, xi_line, xf_line,
51-
color=colors[name], linewidth=(h * 0.6))
52-
53-
ax.set_xlim(0, X)
54-
ax.set_ylim(0, Y)
55-
ax.set_axis_off()
16+
import matplotlib.pyplot as plt
17+
import matplotlib.colors as mcolors
18+
19+
20+
def plot_colortable(colors, title, sort_colors=True, emptycols=0):
21+
22+
cell_width = 185
23+
cell_height = 24
24+
swatch_width = 38
25+
margin = 10
26+
topmargin = 30
27+
28+
# Sort colors by hue, saturation, value and name.
29+
by_hsv = ((tuple(mcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name)
30+
for name, color in colors.items())
31+
if sort_colors is True:
32+
by_hsv = sorted(by_hsv)
33+
names = [name for hsv, name in by_hsv]
34+
35+
n = len(names)
36+
ncols = 4 - emptycols
37+
nrows = n // ncols + int(n % ncols > 0)
38+
39+
width = cell_width * 4 + 2 * margin
40+
height = cell_height * nrows + margin + topmargin
41+
dpi = 72
42+
43+
fig, ax = plt.subplots(figsize=(width / dpi, height / dpi), dpi=dpi)
44+
fig.subplots_adjust(margin/width, margin/height,
45+
(width-margin)/width, (height-topmargin)/height)
46+
ax.set_xlim(0, cell_width * 4)
47+
ax.set_ylim(cell_height * (nrows-0.5), -cell_height/2.)
48+
ax.yaxis.set_visible(False)
49+
ax.xaxis.set_visible(False)
50+
ax.set_axis_off()
51+
ax.set_title(title, fontsize=20, loc="left")
52+
53+
for i, name in enumerate(names):
54+
row = i % nrows
55+
col = i // nrows
56+
y = row * cell_height
57+
58+
swatch_start_x = cell_width * col
59+
swatch_end_x = cell_width * col + swatch_width
60+
text_pos_x = cell_width * col + swatch_width + 5
61+
62+
ax.text(text_pos_x, y, name, fontsize=12,
63+
horizontalalignment='left',
64+
verticalalignment='center')
65+
66+
ax.hlines(y, swatch_start_x, swatch_end_x,
67+
color=colors[name], linewidth=18)
68+
plt.show()
69+
70+
plot_colortable(mcolors.BASE_COLORS, "Base Colors",
71+
sort_colors=False, emptycols=1)
72+
plot_colortable(mcolors.TABLEAU_COLORS, "Tableau Palette",
73+
sort_colors=False, emptycols=1)
74+
plot_colortable(mcolors.TABLEAUX_COLORS, "New Tableau Palette",
75+
sort_colors=False, emptycols=1)
76+
#sphinx_gallery_thumbnail_number = 4
77+
plot_colortable(mcolors.CSS4_COLORS, "CSS Colors")
5678

57-
fig.subplots_adjust(left=0, right=1,
58-
top=1, bottom=0,
59-
hspace=0, wspace=0)
60-
plt.show()
6179

6280
#############################################################################
6381
#

lib/matplotlib/_cm.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,53 @@ def _gist_yarg(x): return 1 - x
13461346
)
13471347

13481348

1349+
_tabx10colors = [
1350+
"#4e79a7", # blue
1351+
"#f28e2b", # orange
1352+
"#e15759", # red
1353+
"#76b7b2", # cyan
1354+
"#59a14f", # green
1355+
"#edc948", # yellow
1356+
"#b07aa1", # purple
1357+
"#ff9da7", # pink
1358+
"#9c755f", # brown
1359+
"#bab0ac", # grey
1360+
]
1361+
1362+
_tabx20colors = [
1363+
"#4e79a7", # blue
1364+
"#a0cbe8",
1365+
"#f28e2b", # orange
1366+
"#ffbe7d",
1367+
"#59a14f", # green
1368+
"#8cd17d",
1369+
"#b6992d", # yellow # is different from tabx10
1370+
"#f1ce63",
1371+
"#499894", # cyan # is different from tabx10
1372+
"#86bcb6",
1373+
"#e15759", # red
1374+
"#ff9d9a",
1375+
"#79706e", # grey # is different from tabx10
1376+
"#bab0ac",
1377+
"#d37295", # pink # is different from tabx10
1378+
"#fabfd2",
1379+
"#b07aa1", # purple # is different from tabx10
1380+
"#d4a6c8",
1381+
"#9d7660", # brown # is different from tabx10
1382+
"#d7b5a6",
1383+
]
1384+
1385+
_tabx10_data = []
1386+
for c in _tabx10colors:
1387+
d = [int(s, 16)/255. for s in list(map(''.join, zip(*[iter(c[1:])]*2)))]
1388+
_tabx10_data.append(d)
1389+
1390+
_tabx20_data = []
1391+
for c in _tabx20colors:
1392+
d = [int(s, 16)/255. for s in list(map(''.join, zip(*[iter(c[1:])]*2)))]
1393+
_tabx20_data.append(d)
1394+
1395+
13491396
datad = {
13501397
'Blues': _Blues_data,
13511398
'BrBG': _BrBG_data,
@@ -1423,4 +1470,6 @@ def _gist_yarg(x): return 1 - x
14231470
'tab20': {'listed': _tab20_data},
14241471
'tab20b': {'listed': _tab20b_data},
14251472
'tab20c': {'listed': _tab20c_data},
1473+
'tabx10': {'listed': _tabx10_data},
1474+
'tabx20': {'listed': _tabx20_data},
14261475
}

lib/matplotlib/_color_data.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@
3030
TABLEAU_COLORS = OrderedDict(
3131
('tab:' + name, value) for name, value in TABLEAU_COLORS)
3232

33+
# These colors are from Tableau Version 10
34+
TABLEAUX_COLORS = (
35+
("blue", "#4e79a7"),
36+
("orange", "#f28e2b"),
37+
("red", "#e15759"),
38+
("cyan", "#76b7b2"),
39+
("green", "#59a14f"),
40+
("yellow", "#edc948"),
41+
("purple", "#b07aa1"),
42+
("pink", "#ff9da7"),
43+
("brown", "#9c755f"),
44+
("gray", "#bab0ac")
45+
)
46+
# Normalize name to "tabx:<name>" to avoid name collisions.
47+
TABLEAUX_COLORS = OrderedDict(
48+
('tabx:' + name, value) for name, value in TABLEAUX_COLORS)
49+
3350
# This mapping of color names -> hex values is taken from
3451
# a survey run by Randel Monroe see:
3552
# http://blog.xkcd.com/2010/05/03/color-survey-results/

lib/matplotlib/colors.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,21 @@
4141
level (e.g., ``'0.5'``);
4242
* one of ``{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}``;
4343
* a X11/CSS4 color name;
44-
* a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__;
45-
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
46-
* one of ``{'tab:blue', 'tab:orange', 'tab:green',
47-
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
48-
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
49-
'T10' categorical palette (which is the default color cycle);
44+
* a color name from a palette, prefixed with the palette's name:
45+
46+
* a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__;
47+
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
48+
* one of ``{'tab:blue', 'tab:orange', 'tab:green',
49+
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
50+
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from
51+
the 'T10' categorical palette (which is the default color cycle);
52+
* one of ``{'tabx:blue', 'tabx:orange', 'tabx:red', 'tabx:cyan',
53+
'tabx:green', 'tabx:yellow', 'tabx:purple', 'tabx:pink', 'tabx:brown',
54+
'tabx:gray' }`` which are the colors from the
55+
`new Tableau10 categorical palette
56+
<https://www.tableau.com/about/blog/2016/7/colors-upgrade-tableau-10-\
57+
56782>`__;
58+
5059
* a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index
5160
into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``);
5261
the indexing occurs at artist creation time and defaults to black if the
@@ -61,7 +70,8 @@
6170

6271
import numpy as np
6372
import matplotlib.cbook as cbook
64-
from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS
73+
from ._color_data import (BASE_COLORS, TABLEAU_COLORS, TABLEAUX_COLORS,
74+
CSS4_COLORS, XKCD_COLORS)
6575

6676

6777
class _ColorMapping(dict):
@@ -89,6 +99,10 @@ def __delitem__(self, key):
8999
_colors_full_map.update({k.replace('gray', 'grey'): v
90100
for k, v in TABLEAU_COLORS.items()
91101
if 'gray' in k})
102+
_colors_full_map.update(TABLEAUX_COLORS)
103+
_colors_full_map.update({k.replace('gray', 'grey'): v
104+
for k, v in TABLEAUX_COLORS.items()
105+
if 'gray' in k})
92106
_colors_full_map.update(BASE_COLORS)
93107
_colors_full_map = _ColorMapping(_colors_full_map)
94108

tutorials/colors/colormaps.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@
160160

161161
cmaps['Qualitative'] = ['Pastel1', 'Pastel2', 'Paired', 'Accent',
162162
'Dark2', 'Set1', 'Set2', 'Set3',
163-
'tab10', 'tab20', 'tab20b', 'tab20c']
163+
'tab10', 'tab20', 'tab20b', 'tab20c',
164+
'tabx10', 'tabx20']
164165

165166
###############################################################################
166167
# Miscellaneous

tutorials/colors/colors.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@
1212
level (e.g., ``'0.5'``);
1313
* one of ``{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}``;
1414
* a X11/CSS4 color name;
15-
* a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__;
16-
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
17-
* one of ``{'tab:blue', 'tab:orange', 'tab:green',
18-
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
19-
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
20-
'T10' categorical palette (which is the default color cycle);
15+
* a color name from a palette, prefixed with the palette's name:
16+
17+
* a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__;
18+
prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
19+
* one of ``{'tab:blue', 'tab:orange', 'tab:green',
20+
'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
21+
'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from
22+
the 'T10' categorical palette (which is the default color cycle);
23+
* one of ``{'tabx:blue', 'tabx:orange', 'tabx:red', 'tabx:cyan',
24+
'tabx:green', 'tabx:yellow', 'tabx:purple', 'tabx:pink', 'tabx:brown',
25+
'tabx:gray'}`` which are the colors from the
26+
`new Tableau10 categorical palette
27+
<https://www.tableau.com/about/blog/2016/7/colors-upgrade-tableau-10-\
28+
56782>`__;
29+
2130
* a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index
2231
into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``);
2332
the indexing occurs at artist creation time and defaults to black if the

0 commit comments

Comments
 (0)
0