Skip to content

Navigation Menu

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 e23afa2

Browse filesBrowse files
committed
WIP: separate NamedLineStyle into an Enum
1 parent 3200ff9 commit e23afa2
Copy full SHA for e23afa2

File tree

1 file changed

+86
-48
lines changed
Filter options

1 file changed

+86
-48
lines changed

‎lib/matplotlib/_enums.py

Copy file name to clipboardExpand all lines: lib/matplotlib/_enums.py
+86-48Lines changed: 86 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
they define.
1111
"""
1212

13+
from collections import namedtuple
1314
from enum import Enum, auto
1415
from numbers import Number
1516

@@ -19,6 +20,20 @@
1920
class _AutoStringNameEnum(Enum):
2021
"""Automate the ``name = 'name'`` part of making a (str, Enum)."""
2122

23+
def __new__(cls, str_value, *value_aliases):
24+
"""
25+
Override Enum.__new__ to allow aliases.
26+
27+
For more details on strategies for allowing multiple names per enum
28+
instance, see the discussion at
29+
https://stackoverflow.com/questions/24105268/is-it-possible-to-override-new-in-an-enum-to-parse-strings-to-an-instance
30+
"""
31+
obj = cls.__new__(str_value)
32+
obj._value_ = str_value
33+
for alias in value_aliases:
34+
cls._value2member_map_[alias] = obj
35+
return obj
36+
2237
def _generate_next_value_(name, start, count, last_values):
2338
return name
2439

@@ -224,7 +239,7 @@ def demo():
224239
}
225240

226241

227-
class NamedLineStyle(str, _AutoStringNameEnum):
242+
class LineStyle():
228243
"""
229244
Describe if the line is solid or dashed, and the dash pattern, if any.
230245
@@ -258,9 +273,9 @@ class NamedLineStyle(str, _AutoStringNameEnum):
258273
Setting ``onoffseq`` to ``None`` results in a solid *LineStyle*.
259274
260275
The default dashing patterns described in the table above are themselves
261-
all described in this notation, and can therefore be customized by editing
262-
the appropriate ``lines.*_pattern`` *rc* parameter, as described in
263-
:doc:`/tutorials/introductory/customizing`.
276+
defined under the hood using an offset and an onoffseq, and can therefore
277+
be customized by editing the appropriate ``lines.*_pattern`` *rc*
278+
parameter, as described in :doc:`/tutorials/introductory/customizing`.
264279
265280
.. plot::
266281
:alt: Demo of possible LineStyle's.
@@ -271,22 +286,17 @@ class NamedLineStyle(str, _AutoStringNameEnum):
271286
.. note::
272287
273288
In addition to directly taking a ``linestyle`` argument,
274-
`~.lines.Line2D` exposes a ``~.lines.Line2D.set_dashes`` method that
275-
can be used to create a new *LineStyle* by providing just the
276-
``onoffseq``, but does not let you customize the offset. This method is
277-
called when using the keyword *dashes* to the cycler , as shown in
278-
:doc:`property_cycle </tutorials/intermediate/color_cycle>`.
289+
`~.lines.Line2D` exposes a ``~.lines.Line2D.set_dashes`` method (and
290+
the :doc:`property_cycle </tutorials/intermediate/color_cycle>` has a
291+
*dashes* keyword) that can be used to create a new *LineStyle* by
292+
providing just the ``onoffseq``, but does not let you customize the
293+
offset. This method simply sets the underlying linestyle, and is only
294+
kept for backwards compatibility.
279295
"""
280-
solid = auto()
281-
dashed = auto()
282-
dotted = auto()
283-
dashdot = auto()
284-
none = auto()
285-
custom = auto()
286296

287-
class LineStyle(str):
288297

289-
def __init__(self, ls, scale=1):
298+
299+
def __init__(self, ls, offset=None, scale=None):
290300
"""
291301
Parameters
292302
----------
@@ -301,56 +311,57 @@ def __init__(self, ls, scale=1):
301311
"""
302312

303313
self._linestyle_spec = ls
314+
# if isinstance(ls, str):
315+
# if ls in [' ', '', 'None']:
316+
# ls = 'none'
317+
# if ls in _ls_mapper:
318+
# ls = _ls_mapper[ls]
319+
# Enum.__init__(self)
320+
# offset, onoffseq = None, None
321+
# else:
322+
# try:
323+
# offset, onoffseq = ls
324+
# except ValueError: # not enough/too many values to unpack
325+
# raise ValueError('LineStyle should be a string or a 2-tuple, '
326+
# 'instead received: ' + str(ls))
304327
if isinstance(ls, str):
305-
if ls in [' ', '', 'None']:
306-
ls = 'none'
307-
if ls in _ls_mapper:
308-
ls = _ls_mapper[ls]
309-
Enum.__init__(self)
310-
offset, onoffseq = None, None
311-
else:
312-
try:
313-
offset, onoffseq = ls
314-
except ValueError: # not enough/too many values to unpack
315-
raise ValueError('LineStyle should be a string or a 2-tuple, '
316-
'instead received: ' + str(ls))
328+
return
329+
offset, onoffseq = ls
317330
if offset is None:
318331
_api.warn_deprecated(
319332
"3.3", message="Passing the dash offset as None is deprecated "
320333
"since %(since)s and support for it will be removed "
321334
"%(removal)s; pass it as zero instead.")
322335
offset = 0
323-
324-
if onoffseq is not None:
325-
# normalize offset to be positive and shorter than the dash cycle
326-
dsum = sum(onoffseq)
327-
if dsum:
328-
offset %= dsum
329-
if len(onoffseq) % 2 != 0:
330-
raise ValueError('LineStyle onoffseq must be of even length.')
331-
if not all(isinstance(elem, Number) for elem in onoffseq):
332-
raise ValueError('LineStyle onoffseq must be list of floats.')
333-
self._us_offset = offset
334-
self._us_onoffseq = onoffseq
336+
# force 0 <= offset < dash cycle length
337+
self._us_offset, self._us_onoffseq = \
338+
LineStyle._normalize_offset(offset, onoffseq)
335339

336340
def __hash__(self):
337341
if self == LineStyle.custom:
338342
return (self._us_offset, tuple(self._us_onoffseq)).__hash__()
339343
return _AutoStringNameEnum.__hash__(self)
340344

345+
@staticmethod
346+
def _normalize_offset(offset, onoffseq):
347+
"""Normalize offset to be positive and shorter than the dash cycle."""
348+
dsum = sum(onoffseq)
349+
if dsum:
350+
offset %= dsum
341351

342352
def get_dashes(self, lw=1):
343353
"""
344354
Get the (scaled) dash sequence for this `.LineStyle`.
345355
"""
346-
# defer lookup until draw time
356+
# named linestyle lookup happens at draw time (here)
347357
if self._us_offset is None or self._us_onoffseq is None:
348-
self._us_offset, self._us_onoffseq = \
349-
LineStyle._get_dash_pattern(self.name)
350-
# normalize offset to be positive and shorter than the dash cycle
351-
dsum = sum(self._us_onoffseq)
352-
self._us_offset %= dsum
353-
return self._scale_dashes(self._us_offset, self._us_onoffseq, lw)
358+
offset, onoffseq = LineStyle._get_dash_pattern(self.name)
359+
else:
360+
offset, onoff_seq = self._us_offset, self._us_onoffseq
361+
# normalize offset to be positive and shorter than the dash cycle
362+
dsum = sum(onoffseq)
363+
offset %= dsum
364+
return self._scale_dashes(offset, onoffseq, lw)
354365

355366
@staticmethod
356367
def _scale_dashes(offset, dashes, lw):
@@ -462,6 +473,33 @@ def plot_linestyles(ax, linestyles, title):
462473
plt.tight_layout()
463474
plt.show()
464475

476+
def _LineStyle_new(cls, ls, offset=None, scale=None):
477+
if cls is NamedLineStyle or isinstance(ls, NamedLineStyle):
478+
return cls(ls)
479+
elif isinstance(ls, LineStyle):
480+
scale = scale if scale is not None else ls.scale
481+
offset = offset if offset is not None else ls.offset
482+
onoffseq = ls.onoffseq
483+
return LineStyle.__new__(onoffseq, offset=offset, scale=scale)
484+
elif isinstance(ls, str):
485+
return cls(ls)
486+
else:
487+
return super(LineStyle, cls).__new__(cls, ls, offset=offset,
488+
scale=scale)
489+
# if len(onoffseq) % 2 != 0:
490+
# raise ValueError('LineStyle onoffseq must be of even length.')
491+
# if not all(isinstance(elem, Number) for elem in onoffseq):
492+
# raise ValueError('LineStyle onoffseq must be list of floats.')
493+
494+
495+
class NamedLineStyle(LineStyle, _AutoStringNameEnum):
496+
"""There is only one instance of each named LineStyle ever."""
497+
solid = 'solid', '-'
498+
dashed = 'dashed', '--'
499+
dotted = 'dotted', ':'
500+
dashdot = 'dashdot', '-.'
501+
none = 'none', 'None', ' '
502+
465503

466504
LineStyle._ls_mapper = _ls_mapper
467505
LineStyle._deprecated_lineStyles = _deprecated_lineStyles

0 commit comments

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