Skip to content

Commit 44a85b7

Browse files
committed
ENH: Styler.bar: properly support NaNs
1 parent 8b423fe commit 44a85b7

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

doc/source/whatsnew/v0.24.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ Other
686686
- :meth:`~pandas.io.formats.style.Styler.background_gradient` now takes a ``text_color_threshold`` parameter to automatically lighten the text color based on the luminance of the background color. This improves readability with dark background colors without the need to limit the background colormap range. (:issue:`21258`)
687687
- Require at least 0.28.2 version of ``cython`` to support read-only memoryviews (:issue:`21688`)
688688
- :meth:`~pandas.io.formats.style.Styler.background_gradient` now also supports tablewise application (in addition to rowwise and columnwise) with ``axis=None`` (:issue:`15204`)
689-
- :meth:`~pandas.io.formats.style.Styler.bar` now also supports tablewise application (in addition to rowwise and columnwise) with ``axis=None`` and setting clipping range with ``vmin`` and ``vmax`` (:issue:`21548` and :issue:`21526`)
689+
- :meth:`~pandas.io.formats.style.Styler.bar` now also supports tablewise application (in addition to rowwise and columnwise) with ``axis=None`` and setting clipping range with ``vmin`` and ``vmax`` (:issue:`21548` and :issue:`21526`). ``NaN`` values are also handled properly.
690690
-
691691
-
692692
-

pandas/io/formats/style.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -997,8 +997,8 @@ def _bar(s, align, colors, width=100, vmin=None, vmax=None):
997997
"""Draw bar chart in dataframe cells"""
998998

999999
# Get input value range.
1000-
smin = s.values.min() if vmin is None else vmin
1001-
smax = s.values.max() if vmax is None else vmax
1000+
smin = s.min().min() if vmin is None else vmin
1001+
smax = s.max().max() if vmax is None else vmax
10021002
if align == 'mid':
10031003
smin = min(0, smin)
10041004
smax = max(0, smax)
@@ -1025,6 +1025,8 @@ def css_bar(start, end, color):
10251025
return css
10261026

10271027
def css(x):
1028+
if pd.isna(x):
1029+
return ''
10281030
if align == 'left':
10291031
return css_bar(0, x, colors[x > zero])
10301032
else:

pandas/tests/io/formats/test_style.py

+39
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,45 @@ def test_bar_align_mid_vmin_vmax_clipping(self):
651651
}
652652
assert result == expected
653653

654+
def test_bar_align_mid_nans(self):
655+
df = pd.DataFrame({'A': [1, None], 'B': [-1, 3]})
656+
result = df.style.bar(align='mid', axis=None)._compute().ctx
657+
expected = {
658+
(0, 0): ['width: 10em', ' height: 80%',
659+
'background: linear-gradient(90deg, '
660+
'transparent 25.0%, #d65f5f 25.0%, '
661+
'#d65f5f 50.0%, transparent 50.0%)'],
662+
(1, 0): [''],
663+
(0, 1): ['width: 10em', ' height: 80%',
664+
'background: linear-gradient(90deg,'
665+
'#d65f5f 25.0%, transparent 25.0%)'],
666+
(1, 1): ['width: 10em', ' height: 80%',
667+
'background: linear-gradient(90deg, '
668+
'transparent 25.0%, #d65f5f 25.0%, '
669+
'#d65f5f 100.0%, transparent 100.0%)']
670+
}
671+
assert result == expected
672+
673+
def test_bar_align_zero_nans(self):
674+
df = pd.DataFrame({'A': [1, None], 'B': [-1, 2]})
675+
result = df.style.bar(align='zero', axis=None)._compute().ctx
676+
expected = {
677+
(0, 0): ['width: 10em', ' height: 80%',
678+
'background: linear-gradient(90deg, '
679+
'transparent 50.0%, #d65f5f 50.0%, '
680+
'#d65f5f 75.0%, transparent 75.0%)'],
681+
(1, 0): [''],
682+
(0, 1): ['width: 10em', ' height: 80%',
683+
'background: linear-gradient(90deg, '
684+
'transparent 25.0%, #d65f5f 25.0%, '
685+
'#d65f5f 50.0%, transparent 50.0%)'],
686+
(1, 1): ['width: 10em', ' height: 80%',
687+
'background: linear-gradient(90deg, '
688+
'transparent 50.0%, #d65f5f 50.0%, '
689+
'#d65f5f 100.0%, transparent 100.0%)']
690+
}
691+
assert result == expected
692+
654693
def test_bar_bad_align_raises(self):
655694
df = pd.DataFrame({'A': [-100, -60, -30, -20]})
656695
with pytest.raises(ValueError):

0 commit comments

Comments
 (0)