From 81607c39a4e67ecdd9fb9857c1421357d8a4026d Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 24 Mar 2024 15:19:52 +0200 Subject: [PATCH 1/8] Fix BUG-14701 allow multiple groupby groups for boxplot --- pandas/plotting/_matplotlib/boxplot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/plotting/_matplotlib/boxplot.py b/pandas/plotting/_matplotlib/boxplot.py index b41e03d87b275..fb67b65bd733b 100644 --- a/pandas/plotting/_matplotlib/boxplot.py +++ b/pandas/plotting/_matplotlib/boxplot.py @@ -540,7 +540,9 @@ def boxplot_frame_groupby( ax=ax, column=column, fontsize=fontsize, rot=rot, grid=grid, **kwds ) ax.set_title(pprint_thing(key)) - ret.loc[key] = d + # GH 14701 'key' needs to be converted to text as 'key' is a tuple when + # there is more than one group + ret.loc[pprint_thing(key)] = d maybe_adjust_figure(fig, bottom=0.15, top=0.9, left=0.1, right=0.9, wspace=0.2) else: keys, frames = zip(*grouped) From 6a346dd99f1303966833a23af37752eff24930c0 Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 24 Mar 2024 17:23:29 +0200 Subject: [PATCH 2/8] Add test for BUG-14701 allow multiple groupby groups for boxplot --- pandas/tests/plotting/test_boxplot_method.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 2dd45a9abc7a5..4b05dd99e13ee 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -740,3 +740,17 @@ def test_boxplot_multiindex_column(self): expected_xticklabel = ["(bar, one)", "(bar, two)"] result_xticklabel = [x.get_text() for x in axes.get_xticklabels()] assert expected_xticklabel == result_xticklabel + + @pytest.mark.parametrize("group", ["X", ["X", "Y"]]) + def test_boxplot_multi_groupby_groups(self, group): + # GH 14701 + rows = 20 + df = DataFrame( + np.random.default_rng(12).normal(size=(rows, 2)), columns=["Col1", "Col2"] + ) + df["X"] = Series(np.repeat(["A", "B"], int(rows / 2))) + df["Y"] = Series(np.tile(["C", "D"], int(rows / 2))) + pregrouped = df.groupby(group) + _check_plot_works(df.boxplot, by=group, default_axes=True) + _check_plot_works(df.plot.box, by=group, default_axes=True) + _check_plot_works(pregrouped.boxplot, default_axes=True) From 3c741eade1b1e3e7b26e3ce449cdf587b6dad7e2 Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 24 Mar 2024 19:36:21 +0200 Subject: [PATCH 3/8] Add docs for BUG-14701 allow multiple groupby groups for boxplot --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index f748f6e23e003..ec5c2f696da93 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -375,7 +375,7 @@ Period Plotting ^^^^^^^^ -- +- Bug in :meth:`DataFrameGroupBy.boxplot` passes a ``tuple`` instead of a ``string`` when input ``DataFrame`` is pre-grouped using more than one ``column`` (:issue:`14701`) - Groupby/resample/rolling From 6f084e1f413266c2f9bc3e1f055fa378ea334546 Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 31 Mar 2024 10:44:39 +0300 Subject: [PATCH 4/8] Update tests for BUG-14701 allow multiple groupby groups for boxplot --- pandas/tests/plotting/test_boxplot_method.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 4b05dd99e13ee..f8029a1c1ee40 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -750,7 +750,7 @@ def test_boxplot_multi_groupby_groups(self, group): ) df["X"] = Series(np.repeat(["A", "B"], int(rows / 2))) df["Y"] = Series(np.tile(["C", "D"], int(rows / 2))) - pregrouped = df.groupby(group) + grouped = df.groupby(group) _check_plot_works(df.boxplot, by=group, default_axes=True) _check_plot_works(df.plot.box, by=group, default_axes=True) - _check_plot_works(pregrouped.boxplot, default_axes=True) + _check_plot_works(grouped.boxplot, default_axes=True) From a3265292f59008dc16a4cfdd3a47fe2e34f601bb Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 31 Mar 2024 10:46:45 +0300 Subject: [PATCH 5/8] Update docs for BUG-14701 allow multiple groupby groups for boxplot --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 12a7f494d3295..90e1cda413419 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -409,7 +409,7 @@ Period Plotting ^^^^^^^^ -- Bug in :meth:`DataFrameGroupBy.boxplot` passes a ``tuple`` instead of a ``string`` when input ``DataFrame`` is pre-grouped using more than one ``column`` (:issue:`14701`) +- Bug in :meth:`.DataFrameGroupBy.boxplot` passes a ``tuple`` instead of a ``string`` when input ``DataFrame`` is pre-grouped using more than one ``column`` (:issue:`14701`) - Groupby/resample/rolling From 50c0e38d255fab38c5f27b554a58cc946f709ea3 Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 31 Mar 2024 11:04:28 +0300 Subject: [PATCH 6/8] Update logic for BUG-14701 allow multiple groupby groups for boxplot --- pandas/plotting/_matplotlib/boxplot.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/plotting/_matplotlib/boxplot.py b/pandas/plotting/_matplotlib/boxplot.py index fb67b65bd733b..c7f72df74efa0 100644 --- a/pandas/plotting/_matplotlib/boxplot.py +++ b/pandas/plotting/_matplotlib/boxplot.py @@ -533,16 +533,16 @@ def boxplot_frame_groupby( ) axes = flatten_axes(axes) - ret = pd.Series(dtype=object) - + data = {} for (key, group), ax in zip(grouped, axes): d = group.boxplot( ax=ax, column=column, fontsize=fontsize, rot=rot, grid=grid, **kwds ) ax.set_title(pprint_thing(key)) - # GH 14701 'key' needs to be converted to text as 'key' is a tuple when - # there is more than one group - ret.loc[pprint_thing(key)] = d + # GH 14701 refactored to allow the 'key' to be passed as a tuple, + # which occurs when there is more than one group + data[key] = d + ret = pd.Series(data) maybe_adjust_figure(fig, bottom=0.15, top=0.9, left=0.1, right=0.9, wspace=0.2) else: keys, frames = zip(*grouped) From dacaf2d6496a688a606cb0a4f52e33082ac80f76 Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 31 Mar 2024 16:05:50 +0300 Subject: [PATCH 7/8] Extract Series creation from for loop --- pandas/plotting/_matplotlib/boxplot.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/plotting/_matplotlib/boxplot.py b/pandas/plotting/_matplotlib/boxplot.py index c7f72df74efa0..75b24cd42e062 100644 --- a/pandas/plotting/_matplotlib/boxplot.py +++ b/pandas/plotting/_matplotlib/boxplot.py @@ -539,10 +539,8 @@ def boxplot_frame_groupby( ax=ax, column=column, fontsize=fontsize, rot=rot, grid=grid, **kwds ) ax.set_title(pprint_thing(key)) - # GH 14701 refactored to allow the 'key' to be passed as a tuple, - # which occurs when there is more than one group data[key] = d - ret = pd.Series(data) + ret = pd.Series(data) maybe_adjust_figure(fig, bottom=0.15, top=0.9, left=0.1, right=0.9, wspace=0.2) else: keys, frames = zip(*grouped) From e3124c01d03a546294f2e8b24601ad47ed9d8f3f Mon Sep 17 00:00:00 2001 From: thetestspecimen Date: Sun, 31 Mar 2024 16:10:02 +0300 Subject: [PATCH 8/8] Update docs for BUG-14701 allow multiple groupby groups for boxplot --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 90e1cda413419..15e85d0f90c5e 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -409,7 +409,7 @@ Period Plotting ^^^^^^^^ -- Bug in :meth:`.DataFrameGroupBy.boxplot` passes a ``tuple`` instead of a ``string`` when input ``DataFrame`` is pre-grouped using more than one ``column`` (:issue:`14701`) +- Bug in :meth:`.DataFrameGroupBy.boxplot` failed when there were multiple groupings (:issue:`14701`) - Groupby/resample/rolling