Skip to content

Commit d352d5a

Browse files
TST: Improved test coverage for Styler.bar error conditions (#56341)
* Improved test coverage for Styler.bar error conditions * Fixed the code style issue causing test failure * Fixed a Styler.bar bug of missing value * Adopted another tricky way to fix the bug * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added a test for Styler.bar with pyarrow * Updated with code style --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b0ffccd commit d352d5a

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

pandas/io/formats/style.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4082,8 +4082,9 @@ def css_calc(x, left: float, right: float, align: str, color: str | list | tuple
40824082
return ret
40834083

40844084
values = data.to_numpy()
4085-
left = np.nanmin(values) if vmin is None else vmin
4086-
right = np.nanmax(values) if vmax is None else vmax
4085+
# A tricky way to address the issue where np.nanmin/np.nanmax fail to handle pd.NA.
4086+
left = np.nanmin(data.min(skipna=True)) if vmin is None else vmin
4087+
right = np.nanmax(data.max(skipna=True)) if vmax is None else vmax
40874088
z: float = 0 # adjustment to translate data
40884089

40894090
if align == "mid":

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

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
import io
2+
13
import numpy as np
24
import pytest
35

4-
from pandas import DataFrame
6+
from pandas import (
7+
NA,
8+
DataFrame,
9+
read_csv,
10+
)
511

612
pytest.importorskip("jinja2")
713

@@ -305,3 +311,48 @@ def test_bar_value_error_raises():
305311
msg = r"`height` must be a value in \[0, 100\]"
306312
with pytest.raises(ValueError, match=msg):
307313
df.style.bar(height=200).to_html()
314+
315+
316+
def test_bar_color_and_cmap_error_raises():
317+
df = DataFrame({"A": [1, 2, 3, 4]})
318+
msg = "`color` and `cmap` cannot both be given"
319+
# Test that providing both color and cmap raises a ValueError
320+
with pytest.raises(ValueError, match=msg):
321+
df.style.bar(color="#d65f5f", cmap="viridis").to_html()
322+
323+
324+
def test_bar_invalid_color_type_error_raises():
325+
df = DataFrame({"A": [1, 2, 3, 4]})
326+
msg = (
327+
r"`color` must be string or list or tuple of 2 strings,"
328+
r"\(eg: color=\['#d65f5f', '#5fba7d'\]\)"
329+
)
330+
# Test that providing an invalid color type raises a ValueError
331+
with pytest.raises(ValueError, match=msg):
332+
df.style.bar(color=123).to_html()
333+
334+
# Test that providing a color list with more than two elements raises a ValueError
335+
with pytest.raises(ValueError, match=msg):
336+
df.style.bar(color=["#d65f5f", "#5fba7d", "#abcdef"]).to_html()
337+
338+
339+
def test_styler_bar_with_NA_values():
340+
df1 = DataFrame({"A": [1, 2, NA, 4]})
341+
df2 = DataFrame([[NA, NA], [NA, NA]])
342+
expected_substring = "style type="
343+
html_output1 = df1.style.bar(subset="A").to_html()
344+
html_output2 = df2.style.bar(align="left", axis=None).to_html()
345+
assert expected_substring in html_output1
346+
assert expected_substring in html_output2
347+
348+
349+
def test_style_bar_with_pyarrow_NA_values():
350+
data = """name,age,test1,test2,teacher
351+
Adam,15,95.0,80,Ashby
352+
Bob,16,81.0,82,Ashby
353+
Dave,16,89.0,84,Jones
354+
Fred,15,,88,Jones"""
355+
df = read_csv(io.StringIO(data), dtype_backend="pyarrow")
356+
expected_substring = "style type="
357+
html_output = df.style.bar(subset="test1").to_html()
358+
assert expected_substring in html_output

0 commit comments

Comments
 (0)