Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 980e4cd

Browse files
committed
Merge pull request #3795 from chebee7i/style-rcparams
ENH : RcParams/dict as input to matplotlib.style.use
2 parents a981d54 + 0a64840 commit 980e4cd

File tree

2 files changed

+122
-20
lines changed

2 files changed

+122
-20
lines changed

lib/matplotlib/style/core.py

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,53 +39,88 @@ def is_style_file(filename):
3939
return STYLE_FILE_PATTERN.match(filename) is not None
4040

4141

42-
def use(name):
43-
"""Use matplotlib style settings from a known style sheet or from a file.
42+
def use(style):
43+
"""Use matplotlib style settings from a style specification.
4444
4545
Parameters
4646
----------
47-
name : str or list of str
48-
Name of style or path/URL to a style file. For a list of available
49-
style names, see `style.available`. If given a list, each style is
50-
applied from first to last in the list.
47+
style : str, dict, or list
48+
A style specification. Valid options are:
49+
50+
+------+-------------------------------------------------------------+
51+
| str | The name of a style or a path/URL to a style file. For a |
52+
| | list of available style names, see `style.available`. |
53+
+------+-------------------------------------------------------------+
54+
| dict | Dictionary with valid key/value pairs for |
55+
| | `matplotlib.rcParams`. |
56+
+------+-------------------------------------------------------------+
57+
| list | A list of style specifiers (str or dict) applied from first |
58+
| | to last in the list. |
59+
+------+-------------------------------------------------------------+
60+
61+
5162
"""
52-
if cbook.is_string_like(name):
53-
name = [name]
63+
if cbook.is_string_like(style) or hasattr(style, 'keys'):
64+
# If name is a single str or dict, make it a single element list.
65+
styles = [style]
66+
else:
67+
styles = style
68+
69+
for style in styles:
70+
if not cbook.is_string_like(style):
71+
mpl.rcParams.update(style)
72+
continue
5473

55-
for style in name:
5674
if style in library:
5775
mpl.rcParams.update(library[style])
5876
else:
5977
try:
6078
rc = rc_params_from_file(style, use_default_template=False)
6179
mpl.rcParams.update(rc)
62-
except:
80+
except IOError:
6381
msg = ("'%s' not found in the style library and input is "
6482
"not a valid URL or path. See `style.available` for "
6583
"list of available styles.")
66-
raise ValueError(msg % style)
84+
raise IOError(msg % style)
6785

6886

6987
@contextlib.contextmanager
70-
def context(name, after_reset=False):
88+
def context(style, after_reset=False):
7189
"""Context manager for using style settings temporarily.
7290
7391
Parameters
7492
----------
75-
name : str or list of str
76-
Name of style or path/URL to a style file. For a list of available
77-
style names, see `style.available`. If given a list, each style is
78-
applied from first to last in the list.
93+
style : str, dict, or list
94+
A style specification. Valid options are:
95+
96+
+------+-------------------------------------------------------------+
97+
| str | The name of a style or a path/URL to a style file. For a |
98+
| | list of available style names, see `style.available`. |
99+
+------+-------------------------------------------------------------+
100+
| dict | Dictionary with valid key/value pairs for |
101+
| | `matplotlib.rcParams`. |
102+
+------+-------------------------------------------------------------+
103+
| list | A list of style specifiers (str or dict) applied from first |
104+
| | to last in the list. |
105+
+------+-------------------------------------------------------------+
106+
79107
after_reset : bool
80108
If True, apply style after resetting settings to their defaults;
81109
otherwise, apply style on top of the current settings.
82110
"""
83111
initial_settings = mpl.rcParams.copy()
84112
if after_reset:
85113
mpl.rcdefaults()
86-
use(name)
87-
yield
88-
mpl.rcParams.update(initial_settings)
114+
try:
115+
use(style)
116+
except:
117+
# Restore original settings before raising errors during the update.
118+
mpl.rcParams.update(initial_settings)
119+
raise
120+
else:
121+
yield
122+
finally:
123+
mpl.rcParams.update(initial_settings)
89124

90125

91126
def load_base_library():

lib/matplotlib/tests/test_style.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22
unicode_literals)
33

44
import os
5+
import sys
56
import shutil
67
import tempfile
78
from contextlib import contextmanager
89

10+
from nose import SkipTest
11+
from nose.tools import assert_raises
12+
913
import matplotlib as mpl
1014
from matplotlib import style
1115
from matplotlib.style.core import USER_LIBRARY_PATHS, STYLE_EXTENSION
1216

1317
import six
1418

15-
1619
PARAM = 'image.cmap'
1720
VALUE = 'pink'
1821
DUMMY_SETTINGS = {PARAM: VALUE}
@@ -68,6 +71,70 @@ def test_context():
6871
assert mpl.rcParams[PARAM] == 'gray'
6972

7073

74+
def test_context_with_dict():
75+
original_value = 'gray'
76+
other_value = 'blue'
77+
mpl.rcParams[PARAM] = original_value
78+
with style.context({PARAM: other_value}):
79+
assert mpl.rcParams[PARAM] == other_value
80+
assert mpl.rcParams[PARAM] == original_value
81+
82+
83+
def test_context_with_dict_after_namedstyle():
84+
# Test dict after style name where dict modifies the same parameter.
85+
original_value = 'gray'
86+
other_value = 'blue'
87+
mpl.rcParams[PARAM] = original_value
88+
with temp_style('test', DUMMY_SETTINGS):
89+
with style.context(['test', {PARAM: other_value}]):
90+
assert mpl.rcParams[PARAM] == other_value
91+
assert mpl.rcParams[PARAM] == original_value
92+
93+
94+
def test_context_with_dict_before_namedstyle():
95+
# Test dict before style name where dict modifies the same parameter.
96+
original_value = 'gray'
97+
other_value = 'blue'
98+
mpl.rcParams[PARAM] = original_value
99+
with temp_style('test', DUMMY_SETTINGS):
100+
with style.context([{PARAM: other_value}, 'test']):
101+
assert mpl.rcParams[PARAM] == VALUE
102+
assert mpl.rcParams[PARAM] == original_value
103+
104+
105+
def test_context_with_union_of_dict_and_namedstyle():
106+
# Test dict after style name where dict modifies the a different parameter.
107+
original_value = 'gray'
108+
other_param = 'text.usetex'
109+
other_value = True
110+
d = {other_param: other_value}
111+
mpl.rcParams[PARAM] = original_value
112+
mpl.rcParams[other_param] = (not other_value)
113+
with temp_style('test', DUMMY_SETTINGS):
114+
with style.context(['test', d]):
115+
assert mpl.rcParams[PARAM] == VALUE
116+
assert mpl.rcParams[other_param] == other_value
117+
assert mpl.rcParams[PARAM] == original_value
118+
assert mpl.rcParams[other_param] == (not other_value)
119+
120+
121+
def test_context_with_badparam():
122+
if sys.version_info[:2] >= (2, 7):
123+
from collections import OrderedDict
124+
else:
125+
m = "Test can only be run in Python >= 2.7 as it requires OrderedDict"
126+
raise SkipTest(m)
127+
128+
original_value = 'gray'
129+
other_value = 'blue'
130+
d = OrderedDict([(PARAM, original_value), ('badparam', None)])
131+
with style.context({PARAM: other_value}):
132+
assert mpl.rcParams[PARAM] == other_value
133+
x = style.context([d])
134+
assert_raises(KeyError, x.__enter__)
135+
assert mpl.rcParams[PARAM] == other_value
136+
137+
71138
if __name__ == '__main__':
72139
from numpy import testing
73140
testing.run_module_suite()

0 commit comments

Comments
 (0)