Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2b055f7

Browse files
committed
Allow empty linestyle for collections
1 parent f25c2d0 commit 2b055f7

File tree

10 files changed

+168
-123
lines changed

10 files changed

+168
-123
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7782,7 +7782,7 @@ def spy(self, Z, precision=0, marker=None, markersize=None,
77827782
raise TypeError(
77837783
"spy() got an unexpected keyword argument 'linestyle'")
77847784
ret = mlines.Line2D(
7785-
x, y, linestyle='None', marker=marker, markersize=markersize,
7785+
x, y, linestyle='none', marker=marker, markersize=markersize,
77867786
**kwargs)
77877787
self.add_line(ret)
77887788
nr, nc = Z.shape

lib/matplotlib/collections.py

Lines changed: 72 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"antialiased": ["antialiaseds", "aa"],
2929
"edgecolor": ["edgecolors", "ec"],
3030
"facecolor": ["facecolors", "fc"],
31-
"linestyle": ["linestyles", "dashes", "ls"],
31+
"linestyle": ["linestyles", "ls"],
3232
"linewidth": ["linewidths", "lw"],
3333
"offset_transform": ["transOffset"],
3434
})
@@ -79,7 +79,7 @@ def __init__(self,
7979
edgecolors=None,
8080
facecolors=None,
8181
linewidths=None,
82-
linestyles='solid',
82+
linestyles='-',
8383
capstyle=None,
8484
joinstyle=None,
8585
antialiaseds=None,
@@ -105,15 +105,8 @@ def __init__(self,
105105
Face color for each patch making up the collection.
106106
linewidths : float or list of floats, default: :rc:`patch.linewidth`
107107
Line width for each patch making up the collection.
108-
linestyles : str or tuple or list thereof, default: 'solid'
109-
Valid strings are ['solid', 'dashed', 'dashdot', 'dotted', '-',
110-
'--', '-.', ':']. Dash tuples should be of the form::
111-
112-
(offset, onoffseq),
113-
114-
where *onoffseq* is an even length tuple of on and off ink lengths
115-
in points. For examples, see
116-
:doc:`/gallery/lines_bars_and_markers/linestyles`.
108+
linestyles : str or tuple or list thereof, default: '-'
109+
Line style or list of line styles. See `set_linestyle` for details.
117110
capstyle : `.CapStyle`-like, default: :rc:`patch.capstyle`
118111
Style to use for capping lines for all paths in the collection.
119112
Allowed values are %(CapStyle)s.
@@ -161,11 +154,12 @@ def __init__(self,
161154
cm.ScalarMappable.__init__(self, norm, cmap)
162155
# list of un-scaled dash patterns
163156
# this is needed scaling the dash pattern by linewidth
164-
self._us_linestyles = [(0, None)]
157+
self._unscaled_dash_patterns = [(0, None)]
165158
# list of dash patterns
166-
self._linestyles = [(0, None)]
159+
self._dash_patterns = [(0, None)]
160+
self._linestyles = ['-']
167161
# list of unbroadcast/scaled linewidths
168-
self._us_lw = [0]
162+
self._unscaled_lw = [0]
169163
self._linewidths = [0]
170164
# Flags set by _set_mappable_flags: are colors from mapping an array?
171165
self._face_is_mapped = None
@@ -382,7 +376,7 @@ def draw(self, renderer):
382376
if (len(paths) == 1 and len(trans) <= 1 and
383377
len(facecolors) == 1 and len(edgecolors) == 1 and
384378
len(self._linewidths) == 1 and
385-
all(ls[1] is None for ls in self._linestyles) and
379+
all(dash[1] is None for dash in self._dash_patterns) and
386380
len(self._antialiaseds) == 1 and len(self._urls) == 1 and
387381
self.get_hatch() is None):
388382
if len(trans):
@@ -400,21 +394,23 @@ def draw(self, renderer):
400394
if self._capstyle:
401395
gc.set_capstyle(self._capstyle)
402396

397+
print(do_single_path_optimization)
403398
if do_single_path_optimization:
404399
gc.set_foreground(tuple(edgecolors[0]))
405400
gc.set_linewidth(self._linewidths[0])
406-
gc.set_dashes(*self._linestyles[0])
401+
gc.set_dashes(*self._dash_patterns[0])
407402
gc.set_antialiased(self._antialiaseds[0])
408403
gc.set_url(self._urls[0])
409404
renderer.draw_markers(
410405
gc, paths[0], combined_transform.frozen(),
411406
mpath.Path(offsets), offset_trf, tuple(facecolors[0]))
412407
else:
408+
print(self._linewidths)
413409
renderer.draw_path_collection(
414410
gc, transform.frozen(), paths,
415411
self.get_transforms(), offsets, offset_trf,
416412
self.get_facecolor(), self.get_edgecolor(),
417-
self._linewidths, self._linestyles,
413+
self._linewidths, self._dash_patterns,
418414
self._antialiaseds, self._urls,
419415
"screen") # offset_position, kept for backcompat.
420416

@@ -575,59 +571,75 @@ def set_linewidth(self, lw):
575571
if lw is None:
576572
lw = self._get_default_linewidth()
577573
# get the un-scaled/broadcast lw
578-
self._us_lw = np.atleast_1d(np.asarray(lw))
574+
self._unscaled_lw = np.atleast_1d(np.asarray(lw))
579575

580576
# scale all of the dash patterns.
581-
self._linewidths, self._linestyles = self._bcast_lwls(
582-
self._us_lw, self._us_linestyles)
577+
self._linewidths, self._dash_patterns = self._bcast_lwls(
578+
self._unscaled_lw, self._unscaled_dash_patterns)
583579
self.stale = True
584580

585581
def set_linestyle(self, ls):
586582
"""
587-
Set the linestyle(s) for the collection.
583+
Set the line style(s) for the collection.
584+
585+
Parameters
586+
----------
587+
ls : str or tuple or list thereof
588+
The line style. Possible values:
588589
589-
=========================== =================
590-
linestyle description
591-
=========================== =================
592-
``'-'`` or ``'solid'`` solid line
593-
``'--'`` or ``'dashed'`` dashed line
594-
``'-.'`` or ``'dashdot'`` dash-dotted line
595-
``':'`` or ``'dotted'`` dotted line
596-
=========================== =================
590+
- A string:
597591
598-
Alternatively a dash tuple of the following form can be provided::
592+
========================================== =================
593+
linestyle description
594+
========================================== =================
595+
``'-'`` or ``'solid'`` solid line
596+
``'--'`` or ``'dashed'`` dashed line
597+
``'-.'`` or ``'dashdot'`` dash-dotted line
598+
``':'`` or ``'dotted'`` dotted line
599+
``'none'``, ``'None'``, ``' '``, or ``''`` draw nothing
600+
========================================== =================
599601
600-
(offset, onoffseq),
602+
- Alternatively a dash tuple of the following form can be
603+
provided::
601604
602-
where ``onoffseq`` is an even length tuple of on and off ink in points.
605+
(offset, onoffseq)
603606
604-
Parameters
605-
----------
606-
ls : str or tuple or list thereof
607-
Valid values for individual linestyles include {'-', '--', '-.',
608-
':', '', (offset, on-off-seq)}. See `.Line2D.set_linestyle` for a
609-
complete description.
610-
"""
611-
try:
612-
if isinstance(ls, str):
613-
ls = cbook.ls_mapper.get(ls, ls)
614-
dashes = [mlines._get_dash_pattern(ls)]
615-
else:
616-
try:
617-
dashes = [mlines._get_dash_pattern(ls)]
618-
except ValueError:
619-
dashes = [mlines._get_dash_pattern(x) for x in ls]
607+
where ``onoffseq`` is an even length tuple of on and off ink
608+
in points.
620609
621-
except ValueError as err:
622-
raise ValueError('Do not know how to convert {!r} to '
623-
'dashes'.format(ls)) from err
610+
If a single value is provided, this applies to all objects in the
611+
collection. A list can be provided to set different line styles to
612+
different objects.
613+
614+
For examples see :doc:`/gallery/lines_bars_and_markers/linestyles`.
615+
616+
The ``'dashed'``, ``'dashdot'``, and ``'dotted'`` line styles are
617+
controlled by :rc:`lines.dashed_pattern`,
618+
:rc:`lines.dashdot_pattern`, and :rc:`lines.dotted_pattern`,
619+
respectively.
620+
"""
621+
if isinstance(ls, str):
622+
dashes, ls_norm = map(list, zip(mlines._get_dash_pattern(ls)))
623+
else:
624+
try:
625+
dashes, ls_norm = map(list, zip(mlines._get_dash_pattern(ls)))
626+
except ValueError:
627+
dashes, ls_norm = map(
628+
list, zip(*[mlines._get_dash_pattern(x) for x in ls]))
624629

625630
# get the list of raw 'unscaled' dash patterns
626-
self._us_linestyles = dashes
631+
self._unscaled_dash_patterns = dashes
627632

628633
# broadcast and scale the lw and dash patterns
629-
self._linewidths, self._linestyles = self._bcast_lwls(
630-
self._us_lw, self._us_linestyles)
634+
self._linewidths, self._dash_patterns = self._bcast_lwls(
635+
self._unscaled_lw, self._unscaled_dash_patterns)
636+
self._linestyles = ls_norm
637+
638+
def get_dashes(self):
639+
"""
640+
Return the dash patterns.
641+
"""
642+
return self._dash_patterns
631643

632644
@_docstring.interpd
633645
def set_capstyle(self, cs):
@@ -919,8 +931,10 @@ def update_from(self, other):
919931
self._original_facecolor = other._original_facecolor
920932
self._facecolors = other._facecolors
921933
self._linewidths = other._linewidths
934+
self._unscaled_lw = other._unscaled_lw
922935
self._linestyles = other._linestyles
923-
self._us_linestyles = other._us_linestyles
936+
self._unscaled_dash_patterns = other._unscaled_dash_patterns
937+
self._dash_patterns = other._dash_patterns
924938
self._pickradius = other._pickradius
925939
self._hatch = other._hatch
926940

@@ -1522,7 +1536,7 @@ def __init__(self,
15221536
linelength=1,
15231537
linewidth=None,
15241538
color=None,
1525-
linestyle='solid',
1539+
linestyle='-',
15261540
antialiased=None,
15271541
**kwargs
15281542
):
@@ -1545,14 +1559,8 @@ def __init__(self,
15451559
The line width of the event lines, in points.
15461560
color : color or list of colors, default: :rc:`lines.color`
15471561
The color of the event lines.
1548-
linestyle : str or tuple or list thereof, default: 'solid'
1549-
Valid strings are ['solid', 'dashed', 'dashdot', 'dotted',
1550-
'-', '--', '-.', ':']. Dash tuples should be of the form::
1551-
1552-
(offset, onoffseq),
1553-
1554-
where *onoffseq* is an even length tuple of on and off ink
1555-
in points.
1562+
linestyle : str or tuple or list thereof, default: '-'
1563+
Line style or list of line styles. See `set_linestyle` for details.
15561564
antialiased : bool or list thereof, default: :rc:`lines.antialiased`
15571565
Whether to use antialiasing for drawing the lines.
15581566
**kwargs

lib/matplotlib/legend_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ def get_numpoints(self, legend):
400400

401401
def _default_update_prop(self, legend_handle, orig_handle):
402402
lw = orig_handle.get_linewidths()[0]
403-
dashes = orig_handle._us_linestyles[0]
403+
dashes = orig_handle._unscaled_dash_patterns[0]
404404
color = orig_handle.get_colors()[0]
405405
legend_handle.set_color(color)
406406
legend_handle.set_linestyle(dashes)

lib/matplotlib/lines.py

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,58 @@
3030

3131

3232
def _get_dash_pattern(style):
33-
"""Convert linestyle to dash pattern."""
34-
# go from short hand -> full strings
33+
"""
34+
Convert line style to dash pattern and normalize line style.
35+
"""
36+
orig_style = style # keep copy for error message
3537
if isinstance(style, str):
36-
style = ls_mapper.get(style, style)
38+
# check valid string
39+
_api.check_in_list([*Line2D._lineStyles, *ls_mapper_r],
40+
linestyle=style)
41+
# go from full strings -> short
42+
style = ls_mapper_r.get(style, style)
43+
# normalize empty style
44+
if style in ('', ' ', 'None'):
45+
style = 'none'
46+
ls = style
47+
else: # style is a dash tuple
48+
ls = '--'
49+
3750
# un-dashed styles
38-
if style in ['solid', 'None']:
51+
if style in ('-', 'none'):
3952
offset = 0
4053
dashes = None
4154
# dashed styles
42-
elif style in ['dashed', 'dashdot', 'dotted']:
55+
elif style in ('--', '-.', ':'):
4356
offset = 0
44-
dashes = tuple(rcParams['lines.{}_pattern'.format(style)])
45-
#
57+
dashes = tuple(rcParams[f'lines.{ls_mapper[style]}_pattern'])
58+
# dash tuple
4659
elif isinstance(style, tuple):
4760
offset, dashes = style
4861
if offset is None:
49-
raise ValueError(f'Unrecognized linestyle: {style!r}')
62+
raise ValueError(f'Unrecognized linestyle: {orig_style!r}')
63+
if offset == 0 and dashes is None:
64+
# Actually solid, not dashed
65+
ls = '-'
5066
else:
51-
raise ValueError(f'Unrecognized linestyle: {style!r}')
67+
raise ValueError(f'Unrecognized linestyle: {orig_style!r}')
5268

5369
# normalize offset to be positive and shorter than the dash cycle
5470
if dashes is not None:
71+
try:
72+
if any(dash < 0.0 for dash in dashes):
73+
raise ValueError(
74+
"All values in the dash list must be non-negative")
75+
if len(dashes) and not any(dash > 0.0 for dash in dashes):
76+
raise ValueError(
77+
'At least one value in the dash list must be positive')
78+
except TypeError:
79+
raise ValueError(f'Unrecognized linestyle: {orig_style!r}')
5580
dsum = sum(dashes)
5681
if dsum:
5782
offset %= dsum
5883

59-
return offset, dashes
84+
return (offset, dashes), ls
6085

6186

6287
def _scale_dashes(offset, dashes, lw):
@@ -223,6 +248,7 @@ class Line2D(Artist):
223248
'-.': '_draw_dash_dot',
224249
':': '_draw_dotted',
225250
'None': '_draw_nothing',
251+
'none': '_draw_nothing',
226252
' ': '_draw_nothing',
227253
'': '_draw_nothing',
228254
}
@@ -341,7 +367,7 @@ def __init__(self, xdata, ydata,
341367
self.set_solid_capstyle(solid_capstyle)
342368
self.set_solid_joinstyle(solid_joinstyle)
343369

344-
self._linestyles = None
370+
self._linestyle = None
345371
self._drawstyle = None
346372
self._linewidth = linewidth
347373
self._unscaled_dash_pattern = (0, None) # offset, dash
@@ -1079,12 +1105,12 @@ def set_linewidth(self, w):
10791105

10801106
def set_linestyle(self, ls):
10811107
"""
1082-
Set the linestyle of the line.
1108+
Set the line style of the line.
10831109
10841110
Parameters
10851111
----------
1086-
ls : {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
1087-
Possible values:
1112+
ls : str or tuple
1113+
The line style. Possible values:
10881114
10891115
- A string:
10901116
@@ -1107,17 +1133,13 @@ def set_linestyle(self, ls):
11071133
in points. See also :meth:`set_dashes`.
11081134
11091135
For examples see :doc:`/gallery/lines_bars_and_markers/linestyles`.
1136+
1137+
The ``'dashed'``, ``'dashdot'``, and ``'dotted'`` line styles are
1138+
controlled by :rc:`lines.dashed_pattern`,
1139+
:rc:`lines.dashdot_pattern`, and :rc:`lines.dotted_pattern`,
1140+
respectively.
11101141
"""
1111-
if isinstance(ls, str):
1112-
if ls in [' ', '', 'none']:
1113-
ls = 'None'
1114-
_api.check_in_list([*self._lineStyles, *ls_mapper_r], ls=ls)
1115-
if ls not in self._lineStyles:
1116-
ls = ls_mapper_r[ls]
1117-
self._linestyle = ls
1118-
else:
1119-
self._linestyle = '--'
1120-
self._unscaled_dash_pattern = _get_dash_pattern(ls)
1142+
self._unscaled_dash_pattern, self._linestyle = _get_dash_pattern(ls)
11211143
self._dash_pattern = _scale_dashes(
11221144
*self._unscaled_dash_pattern, self._linewidth)
11231145
self.stale = True
@@ -1272,7 +1294,6 @@ def update_from(self, other):
12721294
self._solidcapstyle = other._solidcapstyle
12731295
self._solidjoinstyle = other._solidjoinstyle
12741296

1275-
self._linestyle = other._linestyle
12761297
self._marker = MarkerStyle(marker=other._marker)
12771298
self._drawstyle = other._drawstyle
12781299

0 commit comments

Comments
 (0)