Skip to content

Navigation Menu

Sign in
Appearance settings

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 0078937

Browse filesBrowse files
story645anntzer
andcommitted
Adds xkcd style sheet, replicates tests using plt.xkcd with xkcd style,
Co-authored-by: Antony Lee <anntzer.lee@gmail.com>
1 parent 3a2a224 commit 0078937
Copy full SHA for 0078937

File tree

6 files changed

+136
-42
lines changed
Filter options

6 files changed

+136
-42
lines changed
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
path.effects rcParam can be set in stylesheet and new xkcd stylesheet
2+
---------------------------------------------------------------------
3+
4+
Can now set the ``path.effects`` :ref:`rcParam in a style sheet <customizing>`
5+
using a list of ``(patheffects function name, {**kwargs})``::
6+
7+
path.effects: ('Normal', ), ('Stroke', {'offset': (1, 2)}), ('withStroke', {'linewidth': 4, 'foreground': 'w'})
8+
9+
10+
This feature means that the xkcd style can be used like any other stylesheet:
11+
12+
.. plot::
13+
:include-source: true
14+
:alt: plot where graph and text appear in a hand drawn comic like style
15+
16+
import numpy as np
17+
import matplotlib.pyplot as plt
18+
19+
x = np.linspace(0, 2* np.pi, 100)
20+
y = np.sin(x)
21+
22+
with plt.style.context('xkcd'):
23+
24+
fig, ax = plt.subplots()
25+
ax.set_title("sine curve")
26+
ax.plot(x, y)

‎galleries/examples/style_sheets/style_sheets_reference.py

Copy file name to clipboardExpand all lines: galleries/examples/style_sheets/style_sheets_reference.py
+22-22Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import matplotlib.pyplot as plt
2424
import numpy as np
2525

26+
import matplotlib as mpl
2627
import matplotlib.colors as mcolors
2728
from matplotlib.patches import Rectangle
2829

@@ -47,7 +48,7 @@ def plot_colored_lines(ax):
4748
def sigmoid(t, t0):
4849
return 1 / (1 + np.exp(-(t - t0)))
4950

50-
nb_colors = len(plt.rcParams['axes.prop_cycle'])
51+
nb_colors = len(mpl.rcParams['axes.prop_cycle'])
5152
shifts = np.linspace(-5, 5, nb_colors)
5253
amplitudes = np.linspace(1, 1.5, nb_colors)
5354
for t0, a in zip(shifts, amplitudes):
@@ -75,14 +76,15 @@ def plot_colored_circles(ax, prng, nb_samples=15):
7576
the color cycle, because different styles may have different numbers
7677
of colors.
7778
"""
78-
for sty_dict, j in zip(plt.rcParams['axes.prop_cycle'](),
79+
for sty_dict, j in zip(mpl.rcParams['axes.prop_cycle'](),
7980
range(nb_samples)):
8081
ax.add_patch(plt.Circle(prng.normal(scale=3, size=2),
8182
radius=1.0, color=sty_dict['color']))
8283
ax.grid(visible=True)
8384

8485
# Add title for enabling grid
85-
plt.title('ax.grid(True)', family='monospace', fontsize='small')
86+
font_family = mpl.rcParams.get('font.family', 'monospace')
87+
ax.set_title('ax.grid(True)', family=font_family, fontsize='medium')
8688

8789
ax.set_xlim([-4, 8])
8890
ax.set_ylim([-5, 6])
@@ -133,11 +135,12 @@ def plot_figure(style_label=""):
133135
# make a suptitle, in the same style for all subfigures,
134136
# except those with dark backgrounds, which get a lighter color:
135137
background_color = mcolors.rgb_to_hsv(
136-
mcolors.to_rgb(plt.rcParams['figure.facecolor']))[2]
138+
mcolors.to_rgb(mpl.rcParams['figure.facecolor']))[2]
137139
if background_color < 0.5:
138140
title_color = [0.8, 0.8, 1]
139141
else:
140142
title_color = np.array([19, 6, 84]) / 256
143+
141144
fig.suptitle(style_label, x=0.01, ha='left', color=title_color,
142145
fontsize=14, fontfamily='DejaVu Sans', fontweight='normal')
143146

@@ -147,28 +150,25 @@ def plot_figure(style_label=""):
147150
plot_colored_lines(axs[3])
148151
plot_histograms(axs[4], prng)
149152
plot_colored_circles(axs[5], prng)
150-
151153
# add divider
152154
rec = Rectangle((1 + 0.025, -2), 0.05, 16,
153155
clip_on=False, color='gray')
154156

155157
axs[4].add_artist(rec)
156158

157-
if __name__ == "__main__":
158-
159-
# Set up a list of all available styles, in alphabetical order but
160-
# the `default` and `classic` ones, which will be forced resp. in
161-
# first and second position.
162-
# styles with leading underscores are for internal use such as testing
163-
# and plot types gallery. These are excluded here.
164-
style_list = ['default', 'classic'] + sorted(
165-
style for style in plt.style.available
166-
if style != 'classic' and not style.startswith('_'))
167-
168-
# Plot a demonstration figure for every available style sheet.
169-
for style_label in style_list:
170-
with plt.rc_context({"figure.max_open_warning": len(style_list)}):
171-
with plt.style.context(style_label):
172-
plot_figure(style_label=style_label)
173159

174-
plt.show()
160+
# Set up a list of all available styles, in alphabetical order but
161+
# the `default` and `classic` ones, which will be forced resp. in
162+
# first and second position.
163+
# styles with leading underscores are for internal use such as testing
164+
# and plot types gallery. These are excluded here.
165+
style_list = ['default', 'classic'] + sorted(
166+
style for style in mpl.style.available
167+
if style != 'classic' and not style.startswith('_'))
168+
169+
# Plot a demonstration figure for every available style sheet:
170+
for style_label in style_list:
171+
with mpl.rc_context({"figure.max_open_warning": len(style_list)}):
172+
with mpl.style.context(style_label, after_reset=True):
173+
plot_figure(style_label=style_label)
174+
plt.show()
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## default xkcd style
2+
3+
# line
4+
lines.linewidth : 2.0
5+
6+
# font
7+
font.family : xkcd, xkcd Script, Comic Neue, Comic Sans MS
8+
font.size : 14.0
9+
10+
# axes
11+
axes.linewidth : 1.5
12+
axes.grid : False
13+
axes.unicode_minus: False
14+
axes.edgecolor: black
15+
16+
# ticks
17+
xtick.major.size : 8
18+
xtick.major.width: 3
19+
ytick.major.size : 8
20+
ytick.major.width: 3
21+
22+
# grids
23+
grid.linewidth: 0.0
24+
25+
# figure
26+
figure.facecolor: white
27+
28+
# path
29+
path.sketch : 1, 100, 2
30+
path.effects: ('withStroke', {'linewidth': 4, 'foreground': 'w' })

‎lib/matplotlib/pyplot.py

Copy file name to clipboardExpand all lines: lib/matplotlib/pyplot.py
+2-20Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -748,26 +748,8 @@ def xkcd(
748748
stack = ExitStack()
749749
stack.callback(dict.update, rcParams, rcParams.copy()) # type: ignore
750750

751-
from matplotlib import patheffects
752-
rcParams.update({
753-
'font.family': ['xkcd', 'xkcd Script', 'Comic Neue', 'Comic Sans MS'],
754-
'font.size': 14.0,
755-
'path.sketch': (scale, length, randomness),
756-
'path.effects': [
757-
patheffects.withStroke(linewidth=4, foreground="w")],
758-
'axes.linewidth': 1.5,
759-
'lines.linewidth': 2.0,
760-
'figure.facecolor': 'white',
761-
'grid.linewidth': 0.0,
762-
'axes.grid': False,
763-
'axes.unicode_minus': False,
764-
'axes.edgecolor': 'black',
765-
'xtick.major.size': 8,
766-
'xtick.major.width': 3,
767-
'ytick.major.size': 8,
768-
'ytick.major.width': 3,
769-
})
770-
751+
rcParams.update({**style.library["xkcd"],
752+
'path.sketch': (scale, length, randomness)})
771753
return stack
772754

773755

‎lib/matplotlib/tests/test_path.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_path.py
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,18 @@ def test_xkcd():
253253
ax.plot(x, y)
254254

255255

256+
@image_comparison(['xkcd.png'], remove_text=True)
257+
def test_xkcd_style():
258+
np.random.seed(0)
259+
260+
x = np.linspace(0, 2 * np.pi, 100)
261+
y = np.sin(x)
262+
263+
with plt.style.context('xkcd'):
264+
fig, ax = plt.subplots()
265+
ax.plot(x, y)
266+
267+
256268
@image_comparison(['xkcd_marker.png'], remove_text=True)
257269
def test_xkcd_marker():
258270
np.random.seed(0)
@@ -269,6 +281,22 @@ def test_xkcd_marker():
269281
ax.plot(x, y3, '^', ms=10)
270282

271283

284+
@image_comparison(['xkcd_marker.png'], remove_text=True)
285+
def test_xkcd_marker_style():
286+
np.random.seed(0)
287+
288+
x = np.linspace(0, 5, 8)
289+
y1 = x
290+
y2 = 5 - x
291+
y3 = 2.5 * np.ones(8)
292+
293+
with plt.style.context('xkcd'):
294+
fig, ax = plt.subplots()
295+
ax.plot(x, y1, '+', ms=10)
296+
ax.plot(x, y2, 'o', ms=10)
297+
ax.plot(x, y3, '^', ms=10)
298+
299+
272300
@image_comparison(['marker_paths.pdf'], remove_text=True)
273301
def test_marker_paths_pdf():
274302
N = 7

‎lib/matplotlib/tests/test_style.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_style.py
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import matplotlib as mpl
1010
from matplotlib import pyplot as plt, style
11+
from matplotlib.testing.decorators import check_figures_equal
1112
from matplotlib.style.core import USER_LIBRARY_PATHS, STYLE_EXTENSION
1213

1314

@@ -169,13 +170,40 @@ def test_xkcd_no_cm():
169170
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
170171

171172

173+
def test_xkcd_no_cm_style():
174+
assert mpl.rcParams["path.sketch"] is None
175+
plt.style.use('xkcd')
176+
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
177+
np.testing.break_cycles()
178+
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
179+
180+
172181
def test_xkcd_cm():
173182
assert mpl.rcParams["path.sketch"] is None
174183
with plt.xkcd():
175184
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
176185
assert mpl.rcParams["path.sketch"] is None
177186

178187

188+
def test_xkcd_cm_style():
189+
assert mpl.rcParams["path.sketch"] is None
190+
with style.context('xkcd'):
191+
assert mpl.rcParams["path.sketch"] == (1, 100, 2)
192+
assert mpl.rcParams["path.sketch"] is None
193+
194+
195+
@check_figures_equal()
196+
def test_xkcd_style(fig_test, fig_ref):
197+
198+
with style.context('xkcd'):
199+
fig_test.subplots().plot([1, 2, 3])
200+
fig_test.text(.5, .5, "Hello World!")
201+
202+
with plt.xkcd():
203+
fig_ref.subplots().plot([1, 2, 3])
204+
fig_ref.text(.5, .5, "Hello World!")
205+
206+
179207
def test_up_to_date_blacklist():
180208
assert mpl.style.core.STYLE_BLACKLIST <= {*mpl.rcsetup._validators}
181209

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.