From 2a3707d9c3472b1a010492322b6946388d4989ae Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Sun, 31 May 2020 23:38:29 +0200 Subject: [PATCH 1/2] Markers with fillstyle 'none' should return False for is_filled() --- lib/matplotlib/markers.py | 5 ++++- lib/matplotlib/tests/test_marker.py | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/markers.py b/lib/matplotlib/markers.py index afa8c105e3c4..e9c5fbc21a99 100644 --- a/lib/matplotlib/markers.py +++ b/lib/matplotlib/markers.py @@ -232,7 +232,10 @@ def _recache(self): self._snap_threshold = None self._joinstyle = 'round' self._capstyle = 'butt' - self._filled = True + # Initial guess: Assume the marker is filled unless the fillstyle is + # set to 'none'. The marker function will override this for unfilled + # markers. + self._filled = self._fillstyle != 'none' self._marker_function() def __bool__(self): diff --git a/lib/matplotlib/tests/test_marker.py b/lib/matplotlib/tests/test_marker.py index e50746165792..982f74bf8aee 100644 --- a/lib/matplotlib/tests/test_marker.py +++ b/lib/matplotlib/tests/test_marker.py @@ -7,6 +7,12 @@ import pytest +def test_marker_fillstyle(): + marker_style = markers.MarkerStyle(marker='o', fillstyle='none') + assert marker_style.get_fillstyle() == 'none' + assert not marker_style.is_filled() + + def test_markers_valid(): marker_style = markers.MarkerStyle() mrk_array = np.array([[-0.5, 0], From d86cc2bab8183fd3288ed474e4dfd33e0f018908 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Mon, 1 Jun 2020 00:14:05 +0200 Subject: [PATCH 2/2] Fix colors for scatter() with unfilled markers Previously, markers with fillstyle='none' still were drawn with a facecolor. --- lib/matplotlib/axes/_axes.py | 10 +++++----- lib/matplotlib/tests/test_axes.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index f1a16cbd6504..81f8aa4ee4d4 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -4393,8 +4393,9 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, - 'none': No patch boundary will be drawn. - A color or sequence of colors. - For non-filled markers, the *edgecolors* kwarg is ignored and - forced to 'face' internally. + For non-filled markers, *edgecolors* is ignored. Instead, the color + is determined like with 'face', i.e. from *c*, *colors*, or + *facecolors*. plotnonfinite : bool, default: False Set to plot points with nonfinite *c*, in conjunction with @@ -4476,7 +4477,6 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, path = marker_obj.get_path().transformed( marker_obj.get_transform()) if not marker_obj.is_filled(): - edgecolors = 'face' if linewidths is None: linewidths = rcParams['lines.linewidth'] elif np.iterable(linewidths): @@ -4488,8 +4488,8 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, collection = mcoll.PathCollection( (path,), scales, - facecolors=colors, - edgecolors=edgecolors, + facecolors=colors if marker_obj.is_filled() else 'none', + edgecolors=edgecolors if marker_obj.is_filled() else colors, linewidths=linewidths, offsets=offsets, transOffset=kwargs.pop('transform', self.transData), diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index e6045868f737..178aba05b071 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -1837,6 +1837,16 @@ def test_scatter_color(self): with pytest.raises(ValueError): plt.scatter([1, 2, 3], [1, 2, 3], color=[1, 2, 3]) + def test_scatter_unfilled(self): + coll = plt.scatter([0, 1, 2], [1, 3, 2], c=['0.1', '0.3', '0.5'], + marker=mmarkers.MarkerStyle('o', fillstyle='none'), + linewidths=[1.1, 1.2, 1.3]) + assert coll.get_facecolors().shape == (0, 4) # no facecolors + assert_array_equal(coll.get_edgecolors(), [[0.1, 0.1, 0.1, 1], + [0.3, 0.3, 0.3, 1], + [0.5, 0.5, 0.5, 1]]) + assert_array_equal(coll.get_linewidths(), [1.1, 1.2, 1.3]) + def test_scatter_size_arg_size(self): x = np.arange(4) with pytest.raises(ValueError):