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

Skip to content

Commit 6450ce2

Browse files
authored
Merge pull request #8040 from afvincent/wip_relax_grid_ls_validation
ENH: Stricter validation of line style rcParams (and extended accepted types for `grid.linestyle`)
2 parents f99c366 + aabf385 commit 6450ce2

File tree

4 files changed

+111
-19
lines changed

4 files changed

+111
-19
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Validation of line style rcParams
2+
---------------------------------
3+
4+
Stricter validation
5+
```````````````````
6+
The validation of rcParams that are related to line styles
7+
(``lines.linestyle``, ``boxplot.*.linestyle``, ``grid.linestyle`` and
8+
``contour.negative_linestyle``) now effectively checks that the values
9+
are valid line styles. Strings like ``dashed`` or ``--`` are accepted,
10+
as well as even-length sequences of on-off ink like ``[1, 1.65]``. In
11+
this latter case, the offset value is handled internally and should *not*
12+
be provided by the user.
13+
14+
The validation is case-insensitive.
15+
16+
Deprecation of the former validators for ``contour.negative_linestyle``
17+
```````````````````````````````````````````````````````````````````````
18+
The new validation scheme replaces the former one used for the
19+
``contour.negative_linestyle`` rcParams, that was limited to ``solid``
20+
and ``dashed`` line styles.
21+
22+
The former public validation functions ``validate_negative_linestyle``
23+
and ``validate_negative_linestyle_legacy`` will be deprecated in 2.1 and
24+
may be removed in 2.3. There are no public functions to replace them.
25+
26+
Examples of use
27+
```````````````
28+
::
29+
30+
grid.linestyle : (1, 3) # loosely dotted grid lines
31+
contour.negative_linestyle : dashdot # previously only solid or dashed

lib/matplotlib/rcsetup.py

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import warnings
2626
import re
2727

28-
from matplotlib.cbook import mplDeprecation
28+
from matplotlib.cbook import mplDeprecation, deprecated, ls_mapper
2929
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
3030
from matplotlib.colors import is_color_like
3131

@@ -530,20 +530,28 @@ def validate_ps_distiller(s):
530530
'top', 'none'])
531531
validate_fillstylelist = _listify_validator(validate_fillstyle)
532532

533-
validate_negative_linestyle = ValidateInStrings('negative_linestyle',
534-
['solid', 'dashed'],
535-
ignorecase=True)
533+
_validate_negative_linestyle = ValidateInStrings('negative_linestyle',
534+
['solid', 'dashed'],
535+
ignorecase=True)
536536

537537

538+
@deprecated('2.1',
539+
addendum=(" See 'validate_negative_linestyle_legacy' " +
540+
"deprecation warning for more information."))
541+
def validate_negative_linestyle(s):
542+
return _validate_negative_linestyle(s)
543+
544+
545+
@deprecated('2.1',
546+
addendum=(" The 'contour.negative_linestyle' rcParam now " +
547+
"follows the same validation as the other rcParams " +
548+
"that are related to line style."))
538549
def validate_negative_linestyle_legacy(s):
539550
try:
540551
res = validate_negative_linestyle(s)
541552
return res
542553
except ValueError:
543554
dashes = validate_nseq_float(2)(s)
544-
warnings.warn("Deprecated negative_linestyle specification; use "
545-
"'solid' or 'dashed'",
546-
mplDeprecation)
547555
return (0, dashes) # (offset, (solid, blank))
548556

549557

@@ -888,6 +896,39 @@ def validate_animation_writer_path(p):
888896
modules["matplotlib.animation"].writers.set_dirty()
889897
return p
890898

899+
# A validator dedicated to the named line styles, based on the items in
900+
# ls_mapper, and a list of possible strings read from Line2D.set_linestyle
901+
_validate_named_linestyle = ValidateInStrings('linestyle',
902+
list(six.iterkeys(ls_mapper)) +
903+
list(six.itervalues(ls_mapper)) +
904+
['None', 'none', ' ', ''],
905+
ignorecase=True)
906+
907+
908+
def _validate_linestyle(ls):
909+
"""
910+
A validator for all possible line styles, the named ones *and*
911+
the on-off ink sequences.
912+
"""
913+
# Named line style, like u'--' or u'solid'
914+
if isinstance(ls, six.text_type):
915+
return _validate_named_linestyle(ls)
916+
917+
# On-off ink (in points) sequence *of even length*.
918+
# Offset is set to None.
919+
try:
920+
if len(ls) % 2 != 0:
921+
# Expecting a sequence of even length
922+
raise ValueError
923+
return (None, validate_nseq_float()(ls))
924+
except (ValueError, TypeError):
925+
# TypeError can be raised by wrong types passed to float()
926+
# (called inside the instance of validate_nseq_float).
927+
pass
928+
929+
raise ValueError("linestyle must be a string or " +
930+
"an even-length sequence of floats.")
931+
891932

892933
# a map from key -> value, converter
893934
defaultParams = {
@@ -912,7 +953,7 @@ def validate_animation_writer_path(p):
912953

913954
# line props
914955
'lines.linewidth': [1.5, validate_float], # line width in points
915-
'lines.linestyle': ['-', six.text_type], # solid line
956+
'lines.linestyle': ['-', _validate_linestyle], # solid line
916957
'lines.color': ['C0', validate_color], # first color in color cycle
917958
'lines.marker': ['None', six.text_type], # marker name
918959
'lines.markeredgewidth': [1.0, validate_float],
@@ -961,31 +1002,31 @@ def validate_animation_writer_path(p):
9611002
'boxplot.flierprops.markerfacecolor': ['none', validate_color_or_auto],
9621003
'boxplot.flierprops.markeredgecolor': ['k', validate_color],
9631004
'boxplot.flierprops.markersize': [6, validate_float],
964-
'boxplot.flierprops.linestyle': ['none', six.text_type],
1005+
'boxplot.flierprops.linestyle': ['none', _validate_linestyle],
9651006
'boxplot.flierprops.linewidth': [1.0, validate_float],
9661007

9671008
'boxplot.boxprops.color': ['k', validate_color],
9681009
'boxplot.boxprops.linewidth': [1.0, validate_float],
969-
'boxplot.boxprops.linestyle': ['-', six.text_type],
1010+
'boxplot.boxprops.linestyle': ['-', _validate_linestyle],
9701011

9711012
'boxplot.whiskerprops.color': ['k', validate_color],
9721013
'boxplot.whiskerprops.linewidth': [1.0, validate_float],
973-
'boxplot.whiskerprops.linestyle': ['-', six.text_type],
1014+
'boxplot.whiskerprops.linestyle': ['-', _validate_linestyle],
9741015

9751016
'boxplot.capprops.color': ['k', validate_color],
9761017
'boxplot.capprops.linewidth': [1.0, validate_float],
977-
'boxplot.capprops.linestyle': ['-', six.text_type],
1018+
'boxplot.capprops.linestyle': ['-', _validate_linestyle],
9781019

9791020
'boxplot.medianprops.color': ['C1', validate_color],
9801021
'boxplot.medianprops.linewidth': [1.0, validate_float],
981-
'boxplot.medianprops.linestyle': ['-', six.text_type],
1022+
'boxplot.medianprops.linestyle': ['-', _validate_linestyle],
9821023

9831024
'boxplot.meanprops.color': ['C2', validate_color],
9841025
'boxplot.meanprops.marker': ['^', six.text_type],
9851026
'boxplot.meanprops.markerfacecolor': ['C2', validate_color],
9861027
'boxplot.meanprops.markeredgecolor': ['C2', validate_color],
9871028
'boxplot.meanprops.markersize': [6, validate_float],
988-
'boxplot.meanprops.linestyle': ['--', six.text_type],
1029+
'boxplot.meanprops.linestyle': ['--', _validate_linestyle],
9891030
'boxplot.meanprops.linewidth': [1.0, validate_float],
9901031

9911032
## font props
@@ -1051,8 +1092,7 @@ def validate_animation_writer_path(p):
10511092
'image.composite_image': [True, validate_bool],
10521093

10531094
# contour props
1054-
'contour.negative_linestyle': ['dashed',
1055-
validate_negative_linestyle_legacy],
1095+
'contour.negative_linestyle': ['dashed', _validate_linestyle],
10561096
'contour.corner_mask': [True, validate_corner_mask],
10571097

10581098
# errorbar props
@@ -1215,7 +1255,7 @@ def validate_animation_writer_path(p):
12151255
'ytick.direction': ['out', six.text_type], # direction of yticks
12161256

12171257
'grid.color': ['#b0b0b0', validate_color], # grid color
1218-
'grid.linestyle': ['-', six.text_type], # solid
1258+
'grid.linestyle': ['-', _validate_linestyle], # solid
12191259
'grid.linewidth': [0.8, validate_float], # in points
12201260
'grid.alpha': [1.0, validate_float],
12211261

lib/matplotlib/tests/test_rcparams.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
validate_nseq_float,
3030
validate_cycler,
3131
validate_hatch,
32-
validate_hist_bins)
32+
validate_hist_bins,
33+
_validate_linestyle)
3334

3435

3536
mpl.rc('text', usetex=False)
@@ -333,6 +334,26 @@ def generate_validator_testcases(valid):
333334
),
334335
'fail': (('aardvark', ValueError),
335336
)
337+
},
338+
{'validator': _validate_linestyle, # NB: case-insensitive
339+
'success': (('-', '-'), ('solid', 'solid'),
340+
('--', '--'), ('dashed', 'dashed'),
341+
('-.', '-.'), ('dashdot', 'dashdot'),
342+
(':', ':'), ('dotted', 'dotted'),
343+
('', ''), (' ', ' '),
344+
('None', 'none'), ('none', 'none'),
345+
('DoTtEd', 'dotted'),
346+
(['1.23', '4.56'], (None, [1.23, 4.56])),
347+
([1.23, 456], (None, [1.23, 456.0])),
348+
([1, 2, 3, 4], (None, [1.0, 2.0, 3.0, 4.0])),
349+
),
350+
'fail': (('aardvark', ValueError), # not a valid string
351+
((None, [1, 2]), ValueError), # (offset, dashes) is not OK
352+
((0, [1, 2]), ValueError), # idem
353+
((-1, [1, 2]), ValueError), # idem
354+
([1, 2, 3], ValueError), # not a sequence of even length
355+
(1.23, ValueError) # not a sequence
356+
)
336357
}
337358
)
338359

matplotlibrc.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ backend : $TEMPLATE_BACKEND
471471
# such as a PDF.
472472

473473
### CONTOUR PLOTS
474-
#contour.negative_linestyle : dashed # dashed | solid
474+
#contour.negative_linestyle : dashed # string or on-off ink sequence
475475
#contour.corner_mask : True # True | False | legacy
476476

477477
### ERRORBAR PLOTS

0 commit comments

Comments
 (0)