8000 Merge pull request #29808 from rcomer/color-sequence-rcparam · matplotlib/matplotlib@a1aa994 · GitHub
[go: up one dir, main page]

Skip to content

Commit a1aa994

Browse files
authored
Merge pull request #29808 from rcomer/color-sequence-rcparam
ENH: set default color cycle to named color sequence
2 parents 05663f7 + 2065369 commit a1aa994

File tree

6 files changed

+58
-9
lines changed

6 files changed

+58
-9
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Setting the default color cycle to a named color sequence
2+
---------------------------------------------------------
3+
4+
The default color cycle may now be configured in the ``matplotlibrc`` file or
5+
a style file to use any of the :doc:`/gallery/color/color_sequences`. For example
6+
7+
.. code-block:: none
8+
9+
axes.prop_cycle : cycler(color='Accent')

galleries/users_explain/artists/color_cycle.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,22 @@
7676
# ----------------------------------------------------------------------
7777
#
7878
# Remember, a custom cycler can be set in your :file:`matplotlibrc`
79-
# file or a style file (:file:`style.mplstyle`) under ``axes.prop_cycle``:
79+
# file or a style file (:file:`style.mplstyle`) under ``axes.prop_cycle``, e.g.
8080
#
81-
# .. code-block:: python
81+
# .. code-block:: none
82+
#
83+
# axes.prop_cycle : cycler(color=['red', 'royalblue', 'gray'])
84+
#
85+
# For colors, a single string may be used either for one of the
86+
# :doc:`/gallery/color/color_sequences`
87+
#
88+
# .. code-block:: none
89+
#
90+
# axes.prop_cycle : cycler(color='Accent')
91+
#
92+
# or if each color has a single character name:
93+
#
94+
# .. code-block:: none
8295
#
8396
# axes.prop_cycle : cycler(color='bgrcmyk')
8497
#

lib/matplotlib/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
# definitions, so it is safe to import from it here.
161161
from . import _api, _version, cbook, _docstring, rcsetup
162162
from matplotlib._api import MatplotlibDeprecationWarning
163+
from matplotlib.colors import _color_sequences as color_sequences
163164
from matplotlib.rcsetup import cycler # noqa: F401
164165

165166

@@ -1531,4 +1532,3 @@ def validate_backend(s):
15311532
from matplotlib.cm import _colormaps as colormaps # noqa: E402
15321533
from matplotlib.cm import _multivar_colormaps as multivar_colormaps # noqa: E402
15331534
from matplotlib.cm import _bivar_colormaps as bivar_colormaps # noqa: E402
1534-
from matplotlib.colors import _color_sequences as color_sequences # noqa: E402

lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,9 @@
417417

418418
#axes.unicode_minus: True # use Unicode for the minus symbol rather than hyphen. See
419419
# https://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes
420-
#axes.prop_cycle: cycler('color', ['1f77b4', 'ff7f0e', '2ca02c', 'd62728', '9467bd', '8c564b', 'e377c2', '7f7f7f', 'bcbd22', '17becf'])
421-
# color cycle for plot lines as list of string color specs:
422-
# single letter, long name, or web-style hex
420+
#axes.prop_cycle: cycler(color='tab10')
421+
# color cycle for plot lines as either a named color sequence or a list
422+
# of string color specs: single letter, long name, or web-style hex
423423
# As opposed to all other parameters in this file, the color
424424
# values must be enclosed in quotes for this parameter,
425425
# e.g. '1f77b4', instead of 1f77b4.

lib/matplotlib/rcsetup.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import numpy as np
2424

25+
import matplotlib as mpl
2526
from matplotlib import _api, cbook
2627
from matplotlib.backends import BackendFilter, backend_registry
2728
from matplotlib.cbook import ls_mapper
@@ -93,6 +94,25 @@ def __call__(self, s):
9394
raise ValueError(msg)
9495

9596

97+
def _single_string_color_list(s, scalar_validator):
98+
"""
99+
Convert the string *s* to a list of colors interpreting it either as a
100+
color sequence name, or a string containing single-letter colors.
101+
"""
102+
try:
103+
colors = mpl.color_sequences[s]
104+
except KeyError:
105+
try:
106+
# Sometimes, a list of colors might be a single string
107+
# of single-letter colornames. So give that a shot.
108+
colors = [scalar_validator(v.strip()) for v in s if v.strip()]
109+
except ValueError:
110+
raise ValueError(f'{s!r} is neither a color sequence name nor can '
111+
'it be interpreted as a list of colors')
112+
113+
return colors
114+
115+
96116
@lru_cache
97117
def _listify_validator(scalar_validator, allow_stringlist=False, *,
98118
n=None, doc=None):
@@ -103,9 +123,8 @@ def f(s):
103123
if v.strip()]
104124
except Exception:
105125
if allow_stringlist:
106-
# Sometimes, a list of colors might be a single string
107-
# of single-letter colornames. So give that a shot.
108-
val = [scalar_validator(v.strip()) for v in s if v.strip()]
126+
# Special handling for colors
127+
val = _single_string_color_list(s, scalar_validator)
109128
else:
110129
raise
111130
# Allow any ordered sequence type -- generators, np.ndarray, pd.Series

lib/matplotlib/tests/test_rcparams.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ def generate_validator_testcases(valid):
257257
{'validator': validate_cycler,
258258
'success': (('cycler("color", "rgb")',
259259
cycler("color", 'rgb')),
260+
('cycler("color", "Dark2")',
261+
cycler("color", mpl.color_sequences["Dark2"])),
260262
(cycler('linestyle', ['-', '--']),
261263
cycler('linestyle', ['-', '--'])),
262264
("""(cycler("color", ["r", "g", "b"]) +
@@ -455,6 +457,12 @@ def test_validator_invalid(validator, arg, exception_type):
455457
validator(arg)
456458

457459

460+
def test_validate_cycler_bad_color_string():
461+
msg = "'foo' is neither a color sequence name nor can it be interpreted as a list"
462+
with pytest.raises(ValueError, match=msg):
463+
validate_cycler("cycler('color', 'foo')")
464+
465+
458466
@pytest.mark.parametrize('weight, parsed_weight', [
459467
('bold', 'bold'),
460468
('BOLD', ValueError), # weight is case-sensitive

0 commit comments

Comments
 (0)
0