Skip to content

Subplot title count fix + fix for issue introduced in earlier PR #61393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8440dde
test case for subplot stacking
eicchen Mar 21, 2025
350a7ec
Removed overlooked print statement
eicchen Mar 21, 2025
b27d1ac
Updated test to check other subplot in figure
eicchen Mar 30, 2025
46c6eaa
Merge commit '5736b9647068d31fdf8673d3528cb64e35060bac' into bar_plot…
eicchen Apr 6, 2025
1fe342a
Updated test cases to include more subplot stacking possibilities
eicchen Apr 8, 2025
de55789
removed savefig() left in test cases
eicchen Apr 8, 2025
e8a6f91
Updated test cases to test more arrangements
eicchen Apr 22, 2025
0d9f5da
Completed function fix (order of subplot input does not matter, need …
eicchen Apr 22, 2025
b356028
appeasing the great pre-commit formatter
eicchen Apr 23, 2025
6cd8a51
Merge branch 'main' into bar_plot_stacking_fix
eicchen Apr 23, 2025
4cc2905
Updated whatsnew
eicchen Apr 23, 2025
9974632
Docstring adjustment
eicchen Apr 23, 2025
ddd3311
Moved self.subplot check to a seperate bool
eicchen Apr 23, 2025
df51168
Added ignore where mypy thinks self.subplots is a bool
eicchen Apr 23, 2025
bfb1dd1
Actually addressed mypy typing
eicchen Apr 23, 2025
e4d5040
Incorperated initial PR comments
eicchen Apr 25, 2025
101ee62
Updated missing () after .all
eicchen Apr 25, 2025
cfa3ada
Initial test cases
eicchen Apr 25, 2025
2a8f126
Addressed more comments on PR
eicchen Apr 25, 2025
9630ee5
Updated '&' to 'and'
eicchen Apr 28, 2025
ab4f7a6
Updated Test cases
eicchen Apr 28, 2025
abe5c3f
Fixed crash when "subplots=True" is used
eicchen Apr 29, 2025
2e8fc9a
Title check checks for subplot length if specified
eicchen May 2, 2025
9dd73d1
Updated Test cases
eicchen Apr 28, 2025
7e50fa0
Title check checks for subplot length if specified
eicchen May 2, 2025
0273814
Merge branch 'subplot_label_count_fix' of https://github.com/eicchen0…
eicchen May 2, 2025
d501e49
Updated test name
eicchen May 2, 2025
584a4a9
Removed extra '_' in test name
eicchen May 2, 2025
16b6792
Fixed issue where expected_total_height returns as a df instead of a …
eicchen May 2, 2025
67f3b41
Merge branch 'bar_plot_stacking_fix' into subplot_label_count_fix
eicchen May 2, 2025
11c7a88
Updated change notes
eicchen May 2, 2025
c895916
Addressed mypy error
eicchen May 2, 2025
878e610
Addresed PR comments
eicchen May 6, 2025
b93eedb
Changed exception message raised and updated test case
eicchen May 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,7 @@ Plotting
- Bug in :meth:`DataFrame.plot.bar` with ``stacked=True`` where labels on stacked bars with zero-height segments were incorrectly positioned at the base instead of the label position of the previous segment (:issue:`59429`)
- Bug in :meth:`DataFrame.plot.line` raising ``ValueError`` when set both color and a ``dict`` style (:issue:`59461`)
- Bug in :meth:`DataFrame.plot` that causes a shift to the right when the frequency multiplier is greater than one. (:issue:`57587`)
- Bug in :meth:`DataFrame.plot` where ``title`` would require extra titles when plotting more than one column per subplot. (:issue:`61019`)
- Bug in :meth:`Series.plot` preventing a line and bar from being aligned on the same plot (:issue:`61161`)
- Bug in :meth:`Series.plot` preventing a line and scatter plot from being aligned (:issue:`61005`)
- Bug in :meth:`Series.plot` with ``kind="pie"`` with :class:`ArrowDtype` (:issue:`59192`)
Expand Down
23 changes: 15 additions & 8 deletions pandas/plotting/_matplotlib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,13 @@ def _adorn_subplots(self, fig: Figure) -> None:
if self.title:
if self.subplots:
if is_list_like(self.title):
if len(self.title) != self.nseries:
if not isinstance(self.subplots, bool):
if len(self.subplots) != len(self.title):
raise ValueError(
f"The number of titles ({len(self.title)}) must equal "
f"the number of subplots ({len(self.subplots)})."
)
elif len(self.title) != self.nseries:
raise ValueError(
"The length of `title` must equal the number "
"of columns if using `title` of type `list` "
Expand Down Expand Up @@ -1934,13 +1940,14 @@ def _make_plot(self, fig: Figure) -> None:

self.subplots: list[Any]

if bool(self.subplots) and self.stacked:
for i, sub_plot in enumerate(self.subplots):
if len(sub_plot) <= 1:
continue
for plot in sub_plot:
_stacked_subplots_ind[int(plot)] = i
_stacked_subplots_offsets.append([0, 0])
if not isinstance(self.subplots, bool):
if bool(self.subplots) and self.stacked:
for i, sub_plot in enumerate(self.subplots):
if len(sub_plot) <= 1:
continue
for plot in sub_plot:
_stacked_subplots_ind[int(plot)] = i
_stacked_subplots_offsets.append([0, 0])

for i, (label, y) in enumerate(self._iter_data(data=data)):
ax = self._get_ax(i)
Expand Down
50 changes: 48 additions & 2 deletions pandas/tests/plotting/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
plt = pytest.importorskip("matplotlib.pyplot")
cm = pytest.importorskip("matplotlib.cm")

import re

from pandas.plotting._matplotlib.style import get_standard_colors


Expand Down Expand Up @@ -727,7 +729,11 @@ def _df_bar_subplot_checker(df_bar_data, df_bar_df, subplot_data_df, subplot_col
].reset_index()
for i in range(len(subplot_columns))
]
expected_total_height = df_bar_df.loc[:, subplot_columns].sum(axis=1)

if len(subplot_columns) == 1:
expected_total_height = df_bar_df.loc[:, subplot_columns[0]]
else:
expected_total_height = df_bar_df.loc[:, subplot_columns].sum(axis=1)

for i in range(len(subplot_columns)):
sliced_df = subplot_sliced_by_source[i]
Expand All @@ -743,7 +749,6 @@ def _df_bar_subplot_checker(df_bar_data, df_bar_df, subplot_data_df, subplot_col
tm.assert_series_equal(
height_iter, expected_total_height, check_names=False, check_dtype=False
)

else:
# Checks each preceding bar ends where the next one starts
next_start_coord = subplot_sliced_by_source[i + 1]["y_coord"]
Expand Down Expand Up @@ -816,3 +821,44 @@ def test_bar_2_subplots_1_triple_stacked(df_bar_data, df_bar_df, subplot_divisio
_df_bar_subplot_checker(
df_bar_data, df_bar_df, subplot_data_df_list[i], subplot_division[i]
)


def test_bar_subplots_stacking_bool(df_bar_data, df_bar_df):
subplot_division = [("A"), ("B"), ("C"), ("D")]
ax = df_bar_df.plot(subplots=True, kind="bar", stacked=True)
subplot_data_df_list = _df_bar_xyheight_from_ax_helper(
df_bar_data, ax, subplot_division
)
for i in range(len(subplot_data_df_list)):
_df_bar_subplot_checker(
df_bar_data, df_bar_df, subplot_data_df_list[i], subplot_division[i]
)


def test_plot_bar_label_count_default():
df = DataFrame(
[(30, 10, 10, 10), (20, 20, 20, 20), (10, 30, 30, 10)], columns=list("ABCD")
)
df.plot(subplots=True, kind="bar", title=["A", "B", "C", "D"])


def test_plot_bar_label_count_expected_fail():
df = DataFrame(
[(30, 10, 10, 10), (20, 20, 20, 20), (10, 30, 30, 10)], columns=list("ABCD")
)
error_regex = re.escape(
"The number of titles (4) must equal the number of subplots (3)."
)
with pytest.raises(ValueError, match=error_regex):
df.plot(
subplots=[("A", "B")],
kind="bar",
title=["A&B", "C", "D", "Extra Title"],
)


def test_plot_bar_label_count_expected_success():
df = DataFrame(
[(30, 10, 10, 10), (20, 20, 20, 20), (10, 30, 30, 10)], columns=list("ABCD")
)
df.plot(subplots=[("A", "B", "D")], kind="bar", title=["A&B&D", "C"])
Loading