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 931cf4a

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 e20e646 commit 931cf4a
Copy full SHA for 931cf4a

File tree

6 files changed

+136
-43
lines changed
Filter options

6 files changed

+136
-43
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-21Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -747,27 +747,8 @@ def xkcd(
747747
stack = ExitStack()
748748
stack.callback(dict.update, rcParams, rcParams.copy()) # type: ignore
749749

750-
from matplotlib import patheffects
751-
rcParams.update({
752-
'font.family': ['xkcd', 'xkcd Script', 'Humor Sans', 'Comic Neue',
753-
'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-
750+
rcParams.update({**style.library["xkcd"],
751+
'path.sketch': (scale, length, randomness)})
771752
return stack
772753

773754

‎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

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

172173

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

179188

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

0 commit comments

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