From 8a45b6ecd012370ce6e0b44f454bbb265a110f21 Mon Sep 17 00:00:00 2001 From: Kundhan73 Date: Tue, 7 Jul 2026 11:48:36 +0530 Subject: [PATCH] Fix grouped_bar TypeError when label/color passed via kwargs (#30739) --- lib/matplotlib/axes/_axes.py | 14 ++++++++++++++ lib/matplotlib/tests/test_axes.py | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 6102fd3d3ed3..3ff77f1308b5 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -3288,6 +3288,20 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing boxplot(values, positions=..., tick_labels=...) """ + # grouped_bar() controls the label and color of each dataset's bars via the + # dedicated *labels* and *colors* parameters, and passes them positionally to + # bar(). A 'label' or 'color' in kwargs would therefore be passed to bar() + # twice, raising an opaque "multiple values for keyword argument" TypeError. + # Reject them early with an actionable message pointing to the plural + # parameters (see #30739). + for kwarg, alternative in [("color", "colors"), ("label", "labels")]: + if kwarg in kwargs: + raise TypeError( + f"grouped_bar() got an unexpected keyword argument '{kwarg}'. " + f"grouped_bar() sets the {kwarg} of each dataset's bars " + f"internally; use '{alternative}' to control the per-dataset " + f"{kwarg}s.") + if cbook._is_pandas_dataframe(heights): if labels is None: labels = heights.columns.tolist() diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 3189076c7655..84f30258e1ac 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -2315,6 +2315,20 @@ def test_grouped_bar_hatch_sequence(): assert rect.get_hatch() == hatch +@pytest.mark.parametrize("kwarg, alternative", [("label", "labels"), + ("color", "colors")]) +def test_grouped_bar_reject_singular_label_color(kwarg, alternative): + # grouped_bar() passes the per-dataset label/color to bar() itself, so a + # 'label' or 'color' in kwargs would be passed twice and raise an opaque + # "multiple values for keyword argument" TypeError. It should instead fail + # early with a message pointing to the plural parameter. See #30739. + fig, ax = plt.subplots() + heights = [np.array([1, 2]), np.array([2, 3])] + with pytest.raises(TypeError, match=f"unexpected keyword argument '{kwarg}'.*" + f"use '{alternative}'"): + ax.grouped_bar(heights, **{kwarg: "dataset"}) + + def test_boxplot_dates_pandas(pd): # smoke test for boxplot and dates in pandas data = np.random.rand(5, 2)