diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 62277f73ddc3..85066c124632 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -771,14 +771,6 @@ class GraphicsContextBase(object): An abstract base class that provides color, line styles, etc... """ - # a mapping from dash styles to suggested offset, dash pairs - dashd = { - 'solid': (None, None), - 'dashed': (0, (6.0, 6.0)), - 'dashdot': (0, (3.0, 5.0, 1.0, 5.0)), - 'dotted': (0, (1.0, 3.0)), - } - def __init__(self): self._alpha = 1.0 self._forced_alpha = False # if True, _alpha overrides A from RGBA @@ -870,7 +862,16 @@ def get_dashes(self): Default value is None """ - return self._dashes + if rcParams['_internal.classic_mode']: + return self._dashes + else: + scale = max(1.0, self.get_linewidth()) + offset, dashes = self._dashes + if offset is not None: + offset = offset * scale + if dashes is not None: + dashes = [x * scale for x in dashes] + return offset, dashes def get_forced_alpha(self): """ @@ -1047,17 +1048,17 @@ def set_linewidth(self, w): def set_linestyle(self, style): """ Set the linestyle to be one of ('solid', 'dashed', 'dashdot', - 'dotted'). One may specify customized dash styles by providing - a tuple of (offset, dash pairs). For example, the predefiend - linestyles have following values.: - - 'dashed' : (0, (6.0, 6.0)), - 'dashdot' : (0, (3.0, 5.0, 1.0, 5.0)), - 'dotted' : (0, (1.0, 3.0)), + 'dotted'). These are defined in the rcParams + `lines.dashed_pattern`, `lines.dashdot_pattern` and + `lines.dotted_pattern`. One may also specify customized dash + styles by providing a tuple of (offset, dash pairs). """ - if style in self.dashd: - offset, dashes = self.dashd[style] + if style == 'solid': + offset, dashes = None, None + elif style in ['dashed', 'dashdot', 'dotted']: + offset = 0 + dashes = rcParams['lines.{}_pattern'.format(style)] elif isinstance(style, tuple): offset, dashes = style else: diff --git a/lib/matplotlib/mpl-data/stylelib/classic.mplstyle b/lib/matplotlib/mpl-data/stylelib/classic.mplstyle index 62de031f6db6..c5cdb660cd63 100644 --- a/lib/matplotlib/mpl-data/stylelib/classic.mplstyle +++ b/lib/matplotlib/mpl-data/stylelib/classic.mplstyle @@ -15,6 +15,9 @@ lines.dash_capstyle : butt # butt|round|projecting lines.solid_joinstyle : round # miter|round|bevel lines.solid_capstyle : projecting # butt|round|projecting lines.antialiased : True # render lines in antialiased (no jaggies) +lines.dashed_pattern : 6, 6 +lines.dashdot_pattern : 3, 5, 1, 5 +lines.dotted_pattern : 1, 3 ### Marker props markers.fillstyle: full diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index f8c239867087..8ede208b8277 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -275,18 +275,18 @@ def validate_maskedarray(v): class validate_nseq_float(object): - def __init__(self, n): + def __init__(self, n=None): self.n = n def __call__(self, s): """return a seq of n floats or raise""" if isinstance(s, six.string_types): - s = s.split(',') + s = [x.strip() for x in s.split(',')] err_msg = _str_err_msg else: err_msg = _seq_err_msg - if len(s) != self.n: + if self.n is not None and len(s) != self.n: raise ValueError(err_msg.format(n=self.n, num=len(s), s=s)) try: @@ -296,18 +296,18 @@ def __call__(self, s): class validate_nseq_int(object): - def __init__(self, n): + def __init__(self, n=None): self.n = n def __call__(self, s): """return a seq of n ints or raise""" if isinstance(s, six.string_types): - s = s.split(',') + s = [x.strip() for x in s.split(',')] err_msg = _str_err_msg else: err_msg = _seq_err_msg - if len(s) != self.n: + if self.n is not None and len(s) != self.n: raise ValueError(err_msg.format(n=self.n, num=len(s), s=s)) try: @@ -836,6 +836,9 @@ def validate_hist_bins(s): 'lines.solid_joinstyle': ['round', validate_joinstyle], 'lines.dash_capstyle': ['butt', validate_capstyle], 'lines.solid_capstyle': ['projecting', validate_capstyle], + 'lines.dashed_pattern': [[2.8, 1.2], validate_nseq_float()], + 'lines.dashdot_pattern': [[4.8, 1.2, 0.8, 1.2], validate_nseq_float()], + 'lines.dotted_pattern': [[1.2, 0.6], validate_nseq_float()], # marker props 'markers.fillstyle': ['full', validate_fillstyle], @@ -992,14 +995,15 @@ def validate_hist_bins(s): 'axes.formatter.use_mathtext': [False, validate_bool], 'axes.formatter.useoffset': [True, validate_bool], 'axes.unicode_minus': [True, validate_bool], - 'axes.color_cycle': [['b', 'g', 'r', 'c', 'm', 'y', 'k'], - deprecate_axes_colorcycle], # cycle of plot - # line colors - # This entry can be either a cycler object or a + 'axes.prop_cycle': [ + ccycler('color', + ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', + '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', + '#bcbd22', '#17becf']), + validate_cycler], # This entry can be either a cycler object or a # string repr of a cycler-object, which gets eval()'ed # to create the object. - 'axes.prop_cycle': [ccycler('color', 'bgrcmyk'), - validate_cycler], + # If 'data', axes limits are set close to the data. # If 'round_numbers' axes limits are set to the nearest round numbers. 'axes.autolimit_mode': [ diff --git a/matplotlibrc.template b/matplotlibrc.template index f52ea5794772..00a3fccb1979 100644 --- a/matplotlibrc.template +++ b/matplotlibrc.template @@ -90,6 +90,11 @@ backend : $TEMPLATE_BACKEND #lines.solid_capstyle : projecting # butt|round|projecting #lines.antialiased : True # render lines in antialiased (no jaggies) +# The three standard dash patterns. These are scaled by the linewidth. +#lines.dashed_pattern : 2.8, 1.2 +#lines.dashdot_pattern : 4.8, 1.2, 0.8, 1.2 +#lines.dotted_pattern : 1.2, 0.6 + #markers.fillstyle: full # full|left|right|bottom|top|none ### PATCHES diff --git a/src/py_converters.cpp b/src/py_converters.cpp index fee7bf8ad463..631763bbc37a 100644 --- a/src/py_converters.cpp +++ b/src/py_converters.cpp @@ -476,7 +476,7 @@ int convert_gcagg(PyObject *pygc, void *gcp) convert_from_attr(pygc, "_antialiased", &convert_bool, &gc->isaa) && convert_from_attr(pygc, "_capstyle", &convert_cap, &gc->cap) && convert_from_attr(pygc, "_joinstyle", &convert_join, &gc->join) && - convert_from_attr(pygc, "_dashes", &convert_dashes, &gc->dashes) && + convert_from_method(pygc, "get_dashes", &convert_dashes, &gc->dashes) && convert_from_attr(pygc, "_cliprect", &convert_rect, &gc->cliprect) && convert_from_method(pygc, "get_clip_path", &convert_clippath, &gc->clippath) && convert_from_method(pygc, "get_snap", &convert_snap, &gc->snap_mode) &&