Skip to content

Commit 493660a

Browse files
committed
Fix scatter edgecolor for unfilled points
For unfilled markers, the edgecolor -- if specified -- has precedence over the facecolor. closes has2k1/plotnine#100
1 parent 09ab2c2 commit 493660a

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Scatter plot unfilled marker edgecolor
2+
--------------------------------------
3+
4+
For :meth:`~matplotlib.axes.Axes.scatter`, when both the `facecolor`
5+
and `edgecolor` are specified for unfilled marker types, the `edgecolor`
6+
is used. Previously, the points took on the `facecolor`.

lib/matplotlib/axes/_axes.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4291,9 +4291,8 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
42914291
- 'none': No patch boundary will be drawn.
42924292
- A color or sequence of colors.
42934293
4294-
For non-filled markers, *edgecolors* is ignored. Instead, the color
4295-
is determined like with 'face', i.e. from *c*, *colors*, or
4296-
*facecolors*.
4294+
For non-filled markers, *edgecolors* kwarg (if it is not None, 'face'
4295+
or 'none') dictates the color of the marker.
42974296
42984297
plotnonfinite : bool, default: False
42994298
Whether to plot points with nonfinite *c* (i.e. ``inf``, ``-inf``
@@ -4378,6 +4377,11 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
43784377
path = marker_obj.get_path().transformed(
43794378
marker_obj.get_transform())
43804379
if not marker_obj.is_filled():
4380+
# In classic mode or non-classic mode
4381+
if edgecolors is None or edgecolors == 'face':
4382+
edgecolors = colors
4383+
colors = 'none'
4384+
43814385
if linewidths is None:
43824386
linewidths = rcParams['lines.linewidth']
43834387
elif np.iterable(linewidths):
@@ -4389,8 +4393,8 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
43894393

43904394
collection = mcoll.PathCollection(
43914395
(path,), scales,
4392-
facecolors=colors if marker_obj.is_filled() else 'none',
4393-
edgecolors=edgecolors if marker_obj.is_filled() else colors,
4396+
facecolors=colors,
4397+
edgecolors=edgecolors,
43944398
linewidths=linewidths,
43954399
offsets=offsets,
43964400
transOffset=kwargs.pop('transform', self.transData),

lib/matplotlib/tests/test_axes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,6 +2367,21 @@ def get_next_color():
23672367
c, None, kwargs={}, xsize=2, get_next_color_func=get_next_color)
23682368

23692369

2370+
@pytest.mark.parametrize(('facecolor', 'edgecolor', 'expected_color'), [
2371+
('red', 'cyan', 'cyan'),
2372+
(None, 'cyan', 'cyan'),
2373+
('red', None, 'red')
2374+
])
2375+
def test_scatter_edgecolor(facecolor, edgecolor, expected_color):
2376+
fig, ax = plt.subplots()
2377+
artist = ax.scatter(x=[1, 2, 3], y=[1, 2, 3], s=550,
2378+
linewidth=5, marker='2',
2379+
facecolor=facecolor,
2380+
edgecolor=edgecolor)
2381+
result_color = artist.get_edgecolor()[0]
2382+
assert mcolors.to_hex(result_color) == mcolors.to_hex(expected_color)
2383+
2384+
23702385
def test_as_mpl_axes_api():
23712386
# tests the _as_mpl_axes api
23722387
from matplotlib.projections.polar import PolarAxes

0 commit comments

Comments
 (0)