From b3e571c3281c333163ab8eea0b2d9d566193b3c6 Mon Sep 17 00:00:00 2001 From: zhuoyahuang97 Date: Sun, 28 Sep 2025 18:32:26 -0400 Subject: [PATCH 1/5] fix boxplot column misorder --- pandas/plotting/_matplotlib/boxplot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/plotting/_matplotlib/boxplot.py b/pandas/plotting/_matplotlib/boxplot.py index 4bb185c51478f..f85b06acfbd14 100644 --- a/pandas/plotting/_matplotlib/boxplot.py +++ b/pandas/plotting/_matplotlib/boxplot.py @@ -214,7 +214,7 @@ def _make_plot(self, fig: Figure) -> None: # values, instead of label which is used as subtitle in this case. # error: "Index" has no attribute "levels"; maybe "nlevels"? levels = self.data.columns.levels # type: ignore[attr-defined] - ticklabels = [pprint_thing(col) for col in levels[0]] + ticklabels = [pprint_thing(col) for col in self.data.columns.get_level_values(0)] # else: ticklabels = [pprint_thing(label)] From 40741ac880579fe95c69f9fefe1251b15745f482 Mon Sep 17 00:00:00 2001 From: zhuoyahuang97 Date: Sun, 28 Sep 2025 19:01:00 -0400 Subject: [PATCH 2/5] add test --- pandas/tests/plotting/test_boxplot_method.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 2267b6197cd80..db6872eb6c246 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -9,6 +9,7 @@ import pytest from pandas import ( + Categorical, DataFrame, MultiIndex, Series, @@ -408,6 +409,14 @@ def test_boxplot_group_no_xlabel_ylabel(self, vert, request): ) assert target_label == pprint_thing(["group"]) + @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning") + def test_boxplot_group_xlabel_ylabel(self, vert): + df = DataFrame({'value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + 'label': ['c', 'c', 'c', 'c', 'b', 'b', 'b', 'b', 'a', 'a']}) + df.label = Categorical(df.label, categories=['c', 'b', 'a'], ordered=True) + ax = df.boxplot(by="label") + xticklabels = ax.get_xticklabels() + assert [x.get_text() for x in xticklabels] == ['c', 'b', 'a'] class TestDataFrameGroupByPlots: def test_boxplot_legacy1(self, hist_df): From 16f35e6deea8a58ea3b6ba645cd10a62946feb3f Mon Sep 17 00:00:00 2001 From: zhuoyahuang97 Date: Sun, 28 Sep 2025 19:03:55 -0400 Subject: [PATCH 3/5] fix failed cicd --- pandas/plotting/_matplotlib/boxplot.py | 7 ++++--- pandas/tests/plotting/test_boxplot_method.py | 15 ++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/pandas/plotting/_matplotlib/boxplot.py b/pandas/plotting/_matplotlib/boxplot.py index f85b06acfbd14..ebcba34043509 100644 --- a/pandas/plotting/_matplotlib/boxplot.py +++ b/pandas/plotting/_matplotlib/boxplot.py @@ -212,9 +212,10 @@ def _make_plot(self, fig: Figure) -> None: # When `by` is assigned, the ticklabels will become unique grouped # values, instead of label which is used as subtitle in this case. - # error: "Index" has no attribute "levels"; maybe "nlevels"? - levels = self.data.columns.levels # type: ignore[attr-defined] - ticklabels = [pprint_thing(col) for col in self.data.columns.get_level_values(0)] # + ticklabels = [ + pprint_thing(col) + for col in self.data.columns.get_level_values(0) + ] else: ticklabels = [pprint_thing(label)] diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index db6872eb6c246..85c509ac1f965 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -410,13 +410,18 @@ def test_boxplot_group_no_xlabel_ylabel(self, vert, request): assert target_label == pprint_thing(["group"]) @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning") - def test_boxplot_group_xlabel_ylabel(self, vert): - df = DataFrame({'value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - 'label': ['c', 'c', 'c', 'c', 'b', 'b', 'b', 'b', 'a', 'a']}) - df.label = Categorical(df.label, categories=['c', 'b', 'a'], ordered=True) + def test_boxplot_group_ordered_ticklabel(self, vert): + df = DataFrame( + { + "value": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + "label": ["c", "c", "c", "c", "b", "b", "b", "b", "a", "a"], + } + ) + df.label = Categorical(df.label, categories=["c", "b", "a"], ordered=True) ax = df.boxplot(by="label") xticklabels = ax.get_xticklabels() - assert [x.get_text() for x in xticklabels] == ['c', 'b', 'a'] + assert [x.get_text() for x in xticklabels] == ["c", "b", "a"] + class TestDataFrameGroupByPlots: def test_boxplot_legacy1(self, hist_df): From 9c17314045f40b8cc78e2daf0a7fcc28ebe5f301 Mon Sep 17 00:00:00 2001 From: zhuoyahuang97 Date: Wed, 15 Oct 2025 13:06:21 -0400 Subject: [PATCH 4/5] add a comment to test --- pandas/tests/plotting/test_boxplot_method.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 85c509ac1f965..d22e3bf885547 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -411,6 +411,7 @@ def test_boxplot_group_no_xlabel_ylabel(self, vert, request): @pytest.mark.filterwarnings("ignore:set_ticklabels:UserWarning") def test_boxplot_group_ordered_ticklabel(self, vert): + # GH 50427 df = DataFrame( { "value": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], From c504058d46554fd4630a4b7beb6ad377b7a0fa48 Mon Sep 17 00:00:00 2001 From: zhuoyahuang97 Date: Sun, 16 Nov 2025 15:04:57 -0500 Subject: [PATCH 5/5] address comment add changelog --- doc/source/whatsnew/v3.0.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 10b56011c9640..499461d9ebcf0 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -1354,6 +1354,7 @@ Other - Bug in ``divmod`` and ``rdivmod`` with :class:`DataFrame`, :class:`Series`, and :class:`Index` with ``bool`` dtypes failing to raise, which was inconsistent with ``__floordiv__`` behavior (:issue:`46043`) - Bug in printing a :class:`DataFrame` with a :class:`DataFrame` stored in :attr:`DataFrame.attrs` raised a ``ValueError`` (:issue:`60455`) - Bug in printing a :class:`Series` with a :class:`DataFrame` stored in :attr:`Series.attrs` raised a ``ValueError`` (:issue:`60568`) +- Bug in :class: `BoxPlot` when column order was not respected in ticklabels. (:issue: `50427`) - Bug when calling :py:func:`copy.copy` on a :class:`DataFrame` or :class:`Series` which would return a deep copy instead of a shallow copy (:issue:`62971`) - Deprecated the keyword ``check_datetimelike_compat`` in :meth:`testing.assert_frame_equal` and :meth:`testing.assert_series_equal` (:issue:`55638`) - Fixed bug in :meth:`Series.replace` and :meth:`DataFrame.replace` when trying to replace :class:`NA` values in a :class:`Float64Dtype` object with ``np.nan``; this now works with ``pd.set_option("mode.nan_is_na", False)`` and is irrelevant otherwise (:issue:`55127`)