diff --git a/doc/api/next_api_changes/deprecations/19341-TH.rst b/doc/api/next_api_changes/deprecations/19341-TH.rst new file mode 100644 index 000000000000..07ab5bdde4b8 --- /dev/null +++ b/doc/api/next_api_changes/deprecations/19341-TH.rst @@ -0,0 +1,5 @@ +``MarkerStyle`` is considered immutable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``MarkerStyle.set_fillstyle()`` and ``MarkerStyle.set_marker()`` are +deprecated. Create a new ``MarkerStyle`` with the respective parameters +instead. diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index bac48f3522c2..6d2d196a3e32 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -534,7 +534,7 @@ def set_fillstyle(self, fs): For examples see :ref:`marker_fill_styles`. """ - self._marker.set_fillstyle(fs) + self.set_marker(MarkerStyle(self._marker.get_marker(), fs)) self.stale = True def set_markevery(self, every): @@ -930,7 +930,8 @@ def get_markeredgecolor(self): if rcParams['_internal.classic_mode']: if self._marker.get_marker() in ('.', ','): return self._color - if self._marker.is_filled() and self.get_fillstyle() != 'none': + if (self._marker.is_filled() + and self._marker.get_fillstyle() != 'none'): return 'k' # Bad hard-wired default... return self._color else: @@ -945,7 +946,7 @@ def get_markeredgewidth(self): return self._markeredgewidth def _get_markerfacecolor(self, alt=False): - if self.get_fillstyle() == 'none': + if self._marker.get_fillstyle() == 'none': return 'none' fc = self._markerfacecoloralt if alt else self._markerfacecolor if cbook._str_lower_equal(fc, 'auto'): @@ -1166,7 +1167,7 @@ def set_marker(self, marker): See `~matplotlib.markers` for full description of possible arguments. """ - self._marker.set_marker(marker) + self._marker = MarkerStyle(marker, self._marker.get_fillstyle()) self.stale = True def set_markeredgecolor(self, ec): diff --git a/lib/matplotlib/markers.py b/lib/matplotlib/markers.py index 403321b38c70..67e00ac261fa 100644 --- a/lib/matplotlib/markers.py +++ b/lib/matplotlib/markers.py @@ -147,6 +147,9 @@ class MarkerStyle: """ A class representing marker types. + Instances are immutable. If you need to change anything, create a new + instance. + Attributes ---------- markers : list @@ -228,8 +231,8 @@ def __init__(self, marker=None, fillstyle=None): One of 'full', 'left', 'right', 'bottom', 'top', 'none'. """ self._marker_function = None - self.set_fillstyle(fillstyle) - self.set_marker(marker) + self._set_fillstyle(fillstyle) + self._set_marker(marker) def _recache(self): if self._marker_function is None: @@ -256,7 +259,11 @@ def is_filled(self): def get_fillstyle(self): return self._fillstyle + @_api.deprecated("3.4", alternative="a new marker") def set_fillstyle(self, fillstyle): + return self._set_fillstyle(fillstyle) + + def _set_fillstyle(self, fillstyle): """ Set the fillstyle. @@ -281,7 +288,11 @@ def get_capstyle(self): def get_marker(self): return self._marker + @_api.deprecated("3.4", alternative="a new marker") def set_marker(self, marker): + return self._set_marker(marker) + + def _set_marker(self, marker): """ Set the marker. diff --git a/lib/matplotlib/tests/test_marker.py b/lib/matplotlib/tests/test_marker.py index 1ac7aaa0d0d8..f85d4ff467ef 100644 --- a/lib/matplotlib/tests/test_marker.py +++ b/lib/matplotlib/tests/test_marker.py @@ -13,27 +13,43 @@ def test_marker_fillstyle(): assert not marker_style.is_filled() -def test_markers_valid(): - marker_style = markers.MarkerStyle() - mrk_array = np.array([[-0.5, 0], - [0.5, 0]]) +@pytest.mark.parametrize('marker', [ + 'o', + 'x', + '', + 'None', + None, + r'$\frac{1}{2}$', + "$\u266B$", + 1, + markers.TICKLEFT, + [[-1, 0], [1, 0]], + np.array([[-1, 0], [1, 0]]), + Path([[0, 0], [1, 0]], [Path.MOVETO, Path.LINETO]), + (5, 0), # a pentagon + (7, 1), # a 7-pointed star + (5, 2), # asterisk + (5, 0, 10), # a pentagon, rotated by 10 degrees + (7, 1, 10), # a 7-pointed star, rotated by 10 degrees + (5, 2, 10), # asterisk, rotated by 10 degrees + markers.MarkerStyle(), + markers.MarkerStyle('o'), +]) +def test_markers_valid(marker): # Checking this doesn't fail. - marker_style.set_marker(mrk_array) + markers.MarkerStyle(marker) -def test_markers_invalid(): - marker_style = markers.MarkerStyle() - mrk_array = np.array([[-0.5, 0, 1, 2, 3]]) - # Checking this does fail. +@pytest.mark.parametrize('marker', [ + 'square', # arbitrary string + np.array([[-0.5, 0, 1, 2, 3]]), # 1D array + (1,), + (5, 3), # second parameter of tuple must be 0, 1, or 2 + (1, 2, 3, 4), +]) +def test_markers_invalid(marker): with pytest.raises(ValueError): - marker_style.set_marker(mrk_array) - - -def test_marker_path(): - marker_style = markers.MarkerStyle() - path = Path([[0, 0], [1, 0]], [Path.MOVETO, Path.LINETO]) - # Checking this doesn't fail. - marker_style.set_marker(path) + markers.MarkerStyle(marker) class UnsnappedMarkerStyle(markers.MarkerStyle):