From 205846733441a9d53caa7c9be36f2d2f1636a43e Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Sat, 12 Nov 2022 00:22:08 +0100 Subject: [PATCH] MNT: Issue a warning instead of logging if RGB(A) passed to scatter(..., c) When to use what: - warnings.warn() in library code if the issue is avoidable and the client application should be modified to eliminate the warning - logging.warning() if there is nothing the client application can do about the situation, but the event should still be noted There are unambiguous ways for the user to specify the color (see the message). Here, the user should take action and switch from using *c* to using *color*. Thus warnings.warn() is the way to go. Closes half of #23422. --- lib/matplotlib/axes/_axes.py | 2 +- lib/matplotlib/tests/test_axes.py | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 876496ef81f0..9ed0254b81ff 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -4394,7 +4394,7 @@ def invalid_shape_exception(csize, xsize): c_is_mapped = True else: # Wrong size; it must not be intended for mapping. if c.shape in ((3,), (4,)): - _log.warning( + _api.warn_external( "*c* argument looks like a single numeric RGB or " "RGBA sequence, which should be avoided as value-" "mapping will have precedence in case its length " diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 1221eb219ab4..8ed4066efdf7 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -1,3 +1,4 @@ +import contextlib from collections import namedtuple import datetime from decimal import Decimal @@ -2638,15 +2639,17 @@ def get_next_color(): "conversion": "^'c' argument must be a color", # bad vals } - if re_key is None: + assert_context = ( + pytest.raises(ValueError, match=REGEXP[re_key]) + if re_key is not None + else pytest.warns(match="argument looks like a single numeric RGB") + if isinstance(c_case, list) and len(c_case) == 3 + else contextlib.nullcontext() + ) + with assert_context: mpl.axes.Axes._parse_scatter_color_args( c=c_case, edgecolors="black", kwargs={}, xsize=xsize, get_next_color_func=get_next_color) - else: - with pytest.raises(ValueError, match=REGEXP[re_key]): - mpl.axes.Axes._parse_scatter_color_args( - c=c_case, edgecolors="black", kwargs={}, xsize=xsize, - get_next_color_func=get_next_color) @mpl.style.context('default') @check_figures_equal(extensions=["png"]) @@ -6803,9 +6806,9 @@ def test_color_length_mismatch(): fig, ax = plt.subplots() with pytest.raises(ValueError): ax.scatter(x, y, c=colors) - c_rgb = (0.5, 0.5, 0.5) - ax.scatter(x, y, c=c_rgb) - ax.scatter(x, y, c=[c_rgb] * N) + with pytest.warns(match="argument looks like a single numeric RGB"): + ax.scatter(x, y, c=(0.5, 0.5, 0.5)) + ax.scatter(x, y, c=[(0.5, 0.5, 0.5)] * N) def test_eventplot_legend(): @@ -7688,7 +7691,8 @@ def test_2dcolor_plot(fig_test, fig_ref): # plot with 1D-color: axs = fig_test.subplots(5) axs[0].plot([1, 2], [1, 2], c=color.reshape(-1)) - axs[1].scatter([1, 2], [1, 2], c=color.reshape(-1)) + with pytest.warns(match="argument looks like a single numeric RGB"): + axs[1].scatter([1, 2], [1, 2], c=color.reshape(-1)) axs[2].step([1, 2], [1, 2], c=color.reshape(-1)) axs[3].hist(np.arange(10), color=color.reshape(-1)) axs[4].bar(np.arange(10), np.arange(10), color=color.reshape(-1))