Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit df49afc

Browse filesBrowse files
NGWitimhoffm
andauthored
Raise warning if both c and facecolors are used in scatter plot (... and related improvements in the test suite). (#29130)
* Raise warning if both c and facecolors are used in scatter plot. In the future we may implement c as edgecolors in that case or cause plot to fail. * Added direct test of _parse method to attempt to make Codecov happy. * Added pragma tags for code coverage to ignore unused but untested simplified return. * Corrected old test that qualified for the new warning. Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
1 parent f2717a5 commit df49afc
Copy full SHA for df49afc

File tree

3 files changed

+65
-9
lines changed
Filter options

3 files changed

+65
-9
lines changed

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4653,6 +4653,14 @@ def _parse_scatter_color_args(c, edgecolors, kwargs, xsize,
46534653
if edgecolors is None and not mpl.rcParams['_internal.classic_mode']:
46544654
edgecolors = mpl.rcParams['scatter.edgecolors']
46554655

4656+
# Raise a warning if both `c` and `facecolor` are set (issue #24404).
4657+
if c is not None and facecolors is not None:
4658+
_api.warn_external(
4659+
"You passed both c and facecolor/facecolors for the markers. "
4660+
"c has precedence over facecolor/facecolors. "
4661+
"This behavior may change in the future."
4662+
)
4663+
46564664
c_was_none = c is None
46574665
if c is None:
46584666
c = (facecolors if facecolors is not None

‎lib/matplotlib/tests/test_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_axes.py
+55-6Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,7 +2942,7 @@ def test_scatter_different_shapes(self, fig_test, fig_ref):
29422942

29432943
@pytest.mark.parametrize('c_case, re_key', params_test_scatter_c)
29442944
def test_scatter_c(self, c_case, re_key):
2945-
def get_next_color():
2945+
def get_next_color(): # pragma: no cover
29462946
return 'blue' # currently unused
29472947

29482948
xsize = 4
@@ -3036,7 +3036,7 @@ def _params(c=None, xsize=2, *, edgecolors=None, **kwargs):
30363036
_result(c=['b', 'g'], colors=np.array([[0, 0, 1, 1], [0, .5, 0, 1]]))),
30373037
])
30383038
def test_parse_scatter_color_args(params, expected_result):
3039-
def get_next_color():
3039+
def get_next_color(): # pragma: no cover
30403040
return 'blue' # currently unused
30413041

30423042
c, colors, _edgecolors = mpl.axes.Axes._parse_scatter_color_args(
@@ -3063,7 +3063,7 @@ def get_next_color():
30633063
(dict(color='r', edgecolor='g'), 'g'),
30643064
])
30653065
def test_parse_scatter_color_args_edgecolors(kwargs, expected_edgecolors):
3066-
def get_next_color():
3066+
def get_next_color(): # pragma: no cover
30673067
return 'blue' # currently unused
30683068

30693069
c = kwargs.pop('c', None)
@@ -3075,7 +3075,7 @@ def get_next_color():
30753075

30763076

30773077
def test_parse_scatter_color_args_error():
3078-
def get_next_color():
3078+
def get_next_color(): # pragma: no cover
30793079
return 'blue' # currently unused
30803080

30813081
with pytest.raises(ValueError,
@@ -3085,6 +3085,55 @@ def get_next_color():
30853085
c, None, kwargs={}, xsize=2, get_next_color_func=get_next_color)
30863086

30873087

3088+
# Warning message tested in the next two tests.
3089+
WARN_MSG = (
3090+
"You passed both c and facecolor/facecolors for the markers. "
3091+
"c has precedence over facecolor/facecolors. This behavior may "
3092+
"change in the future."
3093+
)
3094+
# Test cases shared between direct and integration tests
3095+
COLOR_TEST_CASES = [
3096+
('red', 'blue'),
3097+
(['red', 'blue'], ['green', 'yellow']),
3098+
([[1, 0, 0], [0, 1, 0]], [[0, 0, 1], [1, 1, 0]])
3099+
]
3100+
3101+
3102+
@pytest.mark.parametrize('c, facecolor', COLOR_TEST_CASES)
3103+
def test_parse_c_facecolor_warning_direct(c, facecolor):
3104+
"""Test the internal _parse_scatter_color_args method directly."""
3105+
def get_next_color(): # pragma: no cover
3106+
return 'blue' # currently unused
3107+
3108+
# Test with facecolors (plural)
3109+
with pytest.warns(UserWarning, match=WARN_MSG):
3110+
mpl.axes.Axes._parse_scatter_color_args(
3111+
c=c, edgecolors=None, kwargs={'facecolors': facecolor},
3112+
xsize=2, get_next_color_func=get_next_color)
3113+
3114+
# Test with facecolor (singular)
3115+
with pytest.warns(UserWarning, match=WARN_MSG):
3116+
mpl.axes.Axes._parse_scatter_color_args(
3117+
c=c, edgecolors=None, kwargs={'facecolor': facecolor},
3118+
xsize=2, get_next_color_func=get_next_color)
3119+
3120+
3121+
@pytest.mark.parametrize('c, facecolor', COLOR_TEST_CASES)
3122+
def test_scatter_c_facecolor_warning_integration(c, facecolor):
3123+
"""Test the warning through the actual scatter plot creation."""
3124+
fig, ax = plt.subplots()
3125+
x = [0, 1] if isinstance(c, (list, tuple)) else [0]
3126+
y = x
3127+
3128+
# Test with facecolors (plural)
3129+
with pytest.warns(UserWarning, match=WARN_MSG):
3130+
ax.scatter(x, y, c=c, facecolors=facecolor)
3131+
3132+
# Test with facecolor (singular)
3133+
with pytest.warns(UserWarning, match=WARN_MSG):
3134+
ax.scatter(x, y, c=c, facecolor=facecolor)
3135+
3136+
30883137
def test_as_mpl_axes_api():
30893138
# tests the _as_mpl_axes api
30903139
class Polar:
@@ -9046,8 +9095,8 @@ def test_child_axes_removal():
90469095

90479096
def test_scatter_color_repr_error():
90489097

9049-
def get_next_color():
9050-
return 'blue' # pragma: no cover
9098+
def get_next_color(): # pragma: no cover
9099+
return 'blue' # currently unused
90519100
msg = (
90529101
r"'c' argument must be a color, a sequence of colors"
90539102
r", or a sequence of numbers, not 'red\\n'"

‎lib/matplotlib/tests/test_legend.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_legend.py
+2-3Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -970,13 +970,12 @@ def test_legend_pathcollection_labelcolor_markfacecolor_cmap():
970970
# test the labelcolor for labelcolor='markerfacecolor' on PathCollection
971971
# with colormaps
972972
fig, ax = plt.subplots()
973-
facecolors = mpl.cm.viridis(np.random.rand(10))
973+
colors = mpl.cm.viridis(np.random.rand(10))
974974
ax.scatter(
975975
np.arange(10),
976976
np.arange(10),
977977
label='#1',
978-
c=np.arange(10),
979-
facecolor=facecolors
978+
c=colors
980979
)
981980

982981
leg = ax.legend(labelcolor='markerfacecolor')

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.