Skip to content

Commit 73bf2bb

Browse files
committed
Fix xkcd() not resetting context anymore.
1 parent 0aaf239 commit 73bf2bb

File tree

2 files changed

+47
-24
lines changed

2 files changed

+47
-24
lines changed

lib/matplotlib/pyplot.py

+33-23
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
import six
2222

2323
import sys
24-
import warnings
2524
import time
2625
import types
26+
import warnings
2727

2828
from cycler import cycler
2929
import matplotlib
@@ -389,28 +389,38 @@ def xkcd(scale=1, length=100, randomness=2):
389389
"xkcd mode is not compatible with text.usetex = True")
390390

391391
from matplotlib import patheffects
392-
context = rc_context()
393-
try:
394-
rcParams['font.family'] = ['xkcd', 'Humor Sans', 'Comic Sans MS']
395-
rcParams['font.size'] = 14.0
396-
rcParams['path.sketch'] = (scale, length, randomness)
397-
rcParams['path.effects'] = [
398-
patheffects.withStroke(linewidth=4, foreground="w")]
399-
rcParams['axes.linewidth'] = 1.5
400-
rcParams['lines.linewidth'] = 2.0
401-
rcParams['figure.facecolor'] = 'white'
402-
rcParams['grid.linewidth'] = 0.0
403-
rcParams['axes.grid'] = False
404-
rcParams['axes.unicode_minus'] = False
405-
rcParams['axes.edgecolor'] = 'black'
406-
rcParams['xtick.major.size'] = 8
407-
rcParams['xtick.major.width'] = 3
408-
rcParams['ytick.major.size'] = 8
409-
rcParams['ytick.major.width'] = 3
410-
except:
411-
context.__exit__(*sys.exc_info())
412-
raise
413-
return context
392+
xkcd_ctx = rc_context({
393+
'font.family': ['xkcd', 'Humor Sans', 'Comic Sans MS'],
394+
'font.size': 14.0,
395+
'path.sketch': (scale, length, randomness),
396+
'path.effects': [patheffects.withStroke(linewidth=4, foreground="w")],
397+
'axes.linewidth': 1.5,
398+
'lines.linewidth': 2.0,
399+
'figure.facecolor': 'white',
400+
'grid.linewidth': 0.0,
401+
'axes.grid': False,
402+
'axes.unicode_minus': False,
403+
'axes.edgecolor': 'black',
404+
'xtick.major.size': 8,
405+
'xtick.major.width': 3,
406+
'ytick.major.size': 8,
407+
'ytick.major.width': 3,
408+
})
409+
xkcd_ctx.__enter__()
410+
411+
# In order to make the call to `xkcd` that does not use a context manager
412+
# (cm) work, we need to enter into the cm ourselves, and return a dummy
413+
# cm that does nothing on entry and cleans up the xkcd context on exit.
414+
# Additionally, we need to keep a reference to the dummy cm because it
415+
# would otherwise be exited when GC'd.
416+
417+
class dummy_ctx(object):
418+
def __enter__(self):
419+
pass
420+
421+
__exit__ = xkcd_ctx.__exit__
422+
423+
return dummy_ctx()
414424

415425

416426
## Figures ##

lib/matplotlib/tests/test_style.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import pytest
1212

1313
import matplotlib as mpl
14-
from matplotlib import style
14+
from matplotlib import pyplot as plt, style
1515
from matplotlib.style.core import USER_LIBRARY_PATHS, STYLE_EXTENSION
1616

1717
import six
@@ -158,3 +158,16 @@ def test_alias(equiv_styles):
158158
rc_base = rc_dicts[0]
159159
for nm, rc in zip(equiv_styles[1:], rc_dicts[1:]):
160160
assert rc_base == rc
161+
162+
163+
def test_xkcd_no_cm():
164+
assert mpl.rcParams["path.sketch"] is None
165+
plt.xkcd()
166+
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
167+
168+
169+
def test_xkcd_cm():
170+
assert mpl.rcParams["path.sketch"] is None
171+
with plt.xkcd():
172+
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
173+
assert mpl.rcParams["path.sketch"] is None

0 commit comments

Comments
 (0)