From 071548096f37a6244ff718d381a2229e896d7aaa Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 9 Jun 2022 23:02:00 +0200 Subject: [PATCH] Fix passing stem markerfmt positionally when locs are not given the signature is stem([locs], heads, linefmt=None, ...) So we should support both: ``` stem(heads, linefmt='r') stem(heads, 'r') ``` We had a kwonly deprecation for 3.5 that was aiming at `stem([locs], heads, *, linefmt=None, ...)` but now I'd rather relax this to `stem([locs], heads, linefmt=None, *, ...)` because it's reasonable to still support `stem(heads, 'r')`. That's analogous to `plot(y, 'r')`. The code overhead for supporting both positional and keyword passing for the single `linefmt` parameter is bearable. --- .../deprecations/23232-TH.rst | 6 ++++++ lib/matplotlib/axes/_axes.py | 7 +++++-- lib/matplotlib/tests/test_axes.py | 20 +++++++++++++------ 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 doc/api/next_api_changes/deprecations/23232-TH.rst diff --git a/doc/api/next_api_changes/deprecations/23232-TH.rst b/doc/api/next_api_changes/deprecations/23232-TH.rst new file mode 100644 index 000000000000..c4df9f3bc666 --- /dev/null +++ b/doc/api/next_api_changes/deprecations/23232-TH.rst @@ -0,0 +1,6 @@ +Passing *linefmt* positionally is undeprecated +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Positional use of all formatting parameters in `~.Axes.stem` has been +deprecated since Matplotlib 3.5. This deprecation is relaxed so that one can +still pass *linefmt* positionally, i.e. ``stem(x, y, 'r')``. diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index f5930f82cc4b..a44d9307d8ec 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2900,12 +2900,15 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, heads, = args locs = np.arange(len(heads)) args = () + elif isinstance(args[1], str): + heads, *args = args + locs = np.arange(len(heads)) else: locs, heads, *args = args - if args: + if len(args) > 1: _api.warn_deprecated( "3.5", - message="Passing the linefmt parameter positionally is " + message="Passing the markerfmt parameter positionally is " "deprecated since Matplotlib %(since)s; the " "parameter will become keyword-only %(removal)s.") diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 72e5f63cd2ab..3645a8420920 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -3801,16 +3801,24 @@ def test_stem(use_line_collection): def test_stem_args(): + def _assert_equal(stem_container, expected): + x, y = map(list, stem_container.markerline.get_data()) + assert x == expected[0] + assert y == expected[1] + fig, ax = plt.subplots() - x = list(range(10)) - y = list(range(10)) + x = [1, 3, 5] + y = [9, 8, 7] # Test the call signatures - ax.stem(y) - ax.stem(x, y) - ax.stem(x, y, linefmt='r--') - ax.stem(x, y, linefmt='r--', basefmt='b--') + _assert_equal(ax.stem(y), expected=([0, 1, 2], y)) + _assert_equal(ax.stem(x, y), expected=(x, y)) + _assert_equal(ax.stem(x, y, linefmt='r--'), expected=(x, y)) + _assert_equal(ax.stem(x, y, 'r--'), expected=(x, y)) + _assert_equal(ax.stem(x, y, linefmt='r--', basefmt='b--'), expected=(x, y)) + _assert_equal(ax.stem(y, linefmt='r--'), expected=([0, 1, 2], y)) + _assert_equal(ax.stem(y, 'r--'), expected=([0, 1, 2], y)) def test_stem_dates():