Skip to content

Commit d36138b

Browse files
authored
Fix styling of DataFrame for columns with boolean label (#47848)
* TST: Add test for defaults arg 'subset' * BUG: Fix GH47838 by using boolean mask as default for 'subset' * TST: Reduce tests to one dataframe with boolean columns * CLN: Rename method and add comment * DOC: Add comment to 'whatsnew'
1 parent 0fdad4e commit d36138b

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

doc/source/whatsnew/v1.5.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,7 @@ Styler
10471047
- Bug in :meth:`Styler.set_sticky` leading to white text on white background in dark mode (:issue:`46984`)
10481048
- Bug in :meth:`Styler.to_latex` causing ``UnboundLocalError`` when ``clines="all;data"`` and the ``DataFrame`` has no rows. (:issue:`47203`)
10491049
- Bug in :meth:`Styler.to_excel` when using ``vertical-align: middle;`` with ``xlsxwriter`` engine (:issue:`30107`)
1050+
- Bug when applying styles to a DataFrame with boolean column labels (:issue:`47838`)
10501051

10511052
Metadata
10521053
^^^^^^^^

pandas/io/formats/style.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -2976,6 +2976,12 @@ def hide(
29762976
# A collection of "builtin" styles
29772977
# -----------------------------------------------------------------------
29782978

2979+
def _get_numeric_subset_default(self):
2980+
# Returns a boolean mask indicating where `self.data` has numerical columns.
2981+
# Choosing a mask as opposed to the column names also works for
2982+
# boolean column labels (GH47838).
2983+
return self.data.columns.isin(self.data.select_dtypes(include=np.number))
2984+
29792985
@doc(
29802986
name="background",
29812987
alt="text",
@@ -3119,7 +3125,7 @@ def background_gradient(
31193125
.. figure:: ../../_static/style/{image_prefix}_axNone_gmap.png
31203126
"""
31213127
if subset is None and gmap is None:
3122-
subset = self.data.select_dtypes(include=np.number).columns
3128+
subset = self._get_numeric_subset_default()
31233129

31243130
self.apply(
31253131
_background_gradient,
@@ -3154,7 +3160,7 @@ def text_gradient(
31543160
gmap: Sequence | None = None,
31553161
) -> Styler:
31563162
if subset is None and gmap is None:
3157-
subset = self.data.select_dtypes(include=np.number).columns
3163+
subset = self._get_numeric_subset_default()
31583164

31593165
return self.apply(
31603166
_background_gradient,
@@ -3306,7 +3312,7 @@ def bar(
33063312
raise ValueError(f"`height` must be a value in [0, 100], got {height}")
33073313

33083314
if subset is None:
3309-
subset = self.data.select_dtypes(include=np.number).columns
3315+
subset = self._get_numeric_subset_default()
33103316

33113317
self.apply(
33123318
_bar,

pandas/tests/io/formats/style/test_style.py

+16
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,22 @@ def color_negative_red(val):
746746
df.loc[pct_subset]
747747
df.style.applymap(color_negative_red, subset=pct_subset)
748748

749+
@pytest.mark.parametrize(
750+
"stylefunc", ["background_gradient", "bar", "text_gradient"]
751+
)
752+
def test_subset_for_boolean_cols(self, stylefunc):
753+
# GH47838
754+
df = DataFrame(
755+
[
756+
[1, 2],
757+
[3, 4],
758+
],
759+
columns=[False, True],
760+
)
761+
styled = getattr(df.style, stylefunc)()
762+
styled._compute()
763+
assert set(styled.ctx) == {(0, 0), (0, 1), (1, 0), (1, 1)}
764+
749765
def test_empty(self):
750766
df = DataFrame({"A": [1, 0]})
751767
s = df.style

0 commit comments

Comments
 (0)