Skip to content

Commit 838c6fc

Browse files
committed
Deprecate support for dash-offset = None.
e.g. `plot([1, 2], ls=(None, (4, 4)))` which was previously a synonym for `plot([1, 2], ls=(0, (4, 4)))` which means "dash-pattern of 4pt-long dashes separated by 4pt spaces, with an offset of 0pt at start". Passing None instead of 0 was already not (likely, never) supported for pdf, ps, or svg (an exception is raised at savefig() time for ps/svg, an invalid pdf is generated). There isn't much of a point in supporting None (this also makes e.g. mplcairo more complex because of static typing in C++ extensions), so just deprecate it.
1 parent 4412114 commit 838c6fc

File tree

9 files changed

+47
-23
lines changed

9 files changed

+47
-23
lines changed

doc/api/next_api_changes/deprecations.rst

+9
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,12 @@ variables is deprecated. Additional fonts may be registered using
173173
``matplotlib.compat``
174174
~~~~~~~~~~~~~~~~~~~~~
175175
This module is deprecated.
176+
177+
Passing the dash offset as None
178+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179+
Fine control of dash patterns can be achieved by passing an
180+
``(offset, (on-length, off-length, on-length, off-length, ...))`` pair as the
181+
linestyle property of `.Line2D` and `.LineCollection`. Previously, certain
182+
APIs would accept ``offset = None`` as a synonym for ``offset = 0``, but this
183+
was never implemented e.g. for vector output. Support for ``offset = None`` is
184+
deprecated, set the offset to 0 instead.

examples/text_labels_and_annotations/legend_demo.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def create_artists(self, legend, orig_handle,
153153
lw = orig_handle.get_linewidths()[i]
154154
except IndexError:
155155
lw = orig_handle.get_linewidths()[0]
156-
if dashes[0] is not None:
156+
if dashes[1] is not None:
157157
legline.set_dashes(dashes[1])
158158
legline.set_color(color)
159159
legline.set_transform(trans)

lib/matplotlib/backend_bases.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ def __init__(self):
708708
self._capstyle = 'butt'
709709
self._cliprect = None
710710
self._clippath = None
711-
self._dashes = None, None
711+
self._dashes = 0, None
712712
self._joinstyle = 'round'
713713
self._linestyle = 'solid'
714714
self._linewidth = 1

lib/matplotlib/collections.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ def __init__(self,
115115
cm.ScalarMappable.__init__(self, norm, cmap)
116116
# list of un-scaled dash patterns
117117
# this is needed scaling the dash pattern by linewidth
118-
self._us_linestyles = [(None, None)]
118+
self._us_linestyles = [(0, None)]
119119
# list of dash patterns
120-
self._linestyles = [(None, None)]
120+
self._linestyles = [(0, None)]
121121
# list of unbroadcast/scaled linewidths
122122
self._us_lw = [0]
123123
self._linewidths = [0]
@@ -333,7 +333,7 @@ def draw(self, renderer):
333333
if (len(paths) == 1 and len(trans) <= 1 and
334334
len(facecolors) == 1 and len(edgecolors) == 1 and
335335
len(self._linewidths) == 1 and
336-
self._linestyles == [(None, None)] and
336+
all(ls[1] == None for ls in self._linestyles) and
337337
len(self._antialiaseds) == 1 and len(self._urls) == 1 and
338338
self.get_hatch() is None):
339339
if len(trans):

lib/matplotlib/lines.py

+12-10
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,26 @@ def _get_dash_pattern(style):
3838
style = ls_mapper.get(style, style)
3939
# un-dashed styles
4040
if style in ['solid', 'None']:
41-
offset, dashes = None, None
41+
offset = 0
42+
dashes = None
4243
# dashed styles
4344
elif style in ['dashed', 'dashdot', 'dotted']:
4445
offset = 0
4546
dashes = tuple(rcParams['lines.{}_pattern'.format(style)])
4647
#
4748
elif isinstance(style, tuple):
4849
offset, dashes = style
50+
if offset is None:
51+
cbook.warn_deprecated(
52+
"3.3", message="Passing the dash offset as None is deprecated "
53+
"since %(since)s and support for it will be removed "
54+
"%(removal)s; pass it as zero instead.")
55+
offset = 0
4956
else:
5057
raise ValueError('Unrecognized linestyle: %s' % str(style))
5158

5259
# normalize offset to be positive and shorter than the dash cycle
53-
if dashes is not None and offset is not None:
60+
if dashes is not None:
5461
dsum = sum(dashes)
5562
if dsum:
5663
offset %= dsum
@@ -61,14 +68,9 @@ def _get_dash_pattern(style):
6168
def _scale_dashes(offset, dashes, lw):
6269
if not rcParams['lines.scale_dashes']:
6370
return offset, dashes
64-
65-
scaled_offset = scaled_dashes = None
66-
if offset is not None:
67-
scaled_offset = offset * lw
68-
if dashes is not None:
69-
scaled_dashes = [x * lw if x is not None else None
70-
for x in dashes]
71-
71+
scaled_offset = offset * lw
72+
scaled_dashes = ([x * lw if x is not None else None for x in dashes]
73+
if dashes is not None else None)
7274
return scaled_offset, scaled_dashes
7375

7476

lib/matplotlib/rcsetup.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -557,12 +557,18 @@ def _is_iterable_not_string_like(x):
557557
and _is_iterable_not_string_like(ls[1])
558558
and len(ls[1]) % 2 == 0
559559
and all(isinstance(elem, Number) for elem in ls[1])):
560+
if ls[0] is None:
561+
cbook.warn_deprecated(
562+
"3.3", message="Passing the dash offset as None is deprecated "
563+
"since %(since)s and support for it will be removed "
564+
"%(removal)s; pass it as zero instead.")
565+
ls = (0, ls[1])
560566
return ls
561567
# For backcompat: (on, off, on, off, ...); the offset is implicitly None.
562568
if (_is_iterable_not_string_like(ls)
563569
and len(ls) % 2 == 0
564570
and all(isinstance(elem, Number) for elem in ls)):
565-
return (None, ls)
571+
return (0, ls)
566572
raise ValueError(f"linestyle {ls!r} is not a valid on-off ink sequence.")
567573

568574

lib/matplotlib/tests/test_collections.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def test__EventCollection__get_props():
7676
# check that the default lineoffset matches the input lineoffset
7777
assert props['lineoffset'] == coll.get_lineoffset()
7878
# check that the default linestyle matches the input linestyle
79-
assert coll.get_linestyle() == [(None, None)]
79+
assert coll.get_linestyle() == [(0, None)]
8080
# check that the default color matches the input color
8181
for color in [coll.get_color(), *coll.get_colors()]:
8282
np.testing.assert_array_equal(color, props['color'])
@@ -500,11 +500,11 @@ def test_lslw_bcast():
500500
col.set_linestyles(['-', '-'])
501501
col.set_linewidths([1, 2, 3])
502502

503-
assert col.get_linestyles() == [(None, None)] * 6
503+
assert col.get_linestyles() == [(0, None)] * 6
504504
assert col.get_linewidths() == [1, 2, 3] * 2
505505

506506
col.set_linestyles(['-', '-', '-'])
507-
assert col.get_linestyles() == [(None, None)] * 3
507+
assert col.get_linestyles() == [(0, None)] * 3
508508
assert (col.get_linewidths() == [1, 2, 3]).all()
509509

510510

lib/matplotlib/tests/test_rcparams.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,9 @@ def generate_validator_testcases(valid):
370370
('', ''), (' ', ' '),
371371
('None', 'none'), ('none', 'none'),
372372
('DoTtEd', 'dotted'), # case-insensitive
373-
('1, 3', (None, (1, 3))),
374-
([1.23, 456], (None, [1.23, 456.0])),
375-
([1, 2, 3, 4], (None, [1.0, 2.0, 3.0, 4.0])),
376-
((None, [1, 2]), (None, [1, 2])),
373+
('1, 3', (0, (1, 3))),
374+
([1.23, 456], (0, [1.23, 456.0])),
375+
([1, 2, 3, 4], (0, [1.0, 2.0, 3.0, 4.0])),
377376
((0, [1, 2]), (0, [1, 2])),
378377
((-1, [1, 2]), (-1, [1, 2])),
379378
),

src/py_converters.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ int convert_dashes(PyObject *dashobj, void *dashesp)
237237
if (PyErr_Occurred()) {
238238
return 0;
239239
}
240+
} else {
241+
if (PyErr_WarnEx(PyExc_FutureWarning,
242+
"Passing the dash offset as None is deprecated since "
243+
"Matplotlib 3.3 and will be removed in Matplotlib 3.5; "
244+
"pass it as zero instead.",
245+
1)) {
246+
return 0;
247+
}
240248
}
241249

242250
if (dashes_seq == Py_None) {

0 commit comments

Comments
 (0)