Skip to content

TST: Improved test coverage for Styler.bar error conditions #56341

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 10 commits into from
Dec 11, 2023
Merged
5 changes: 3 additions & 2 deletions pandas/io/formats/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -4082,8 +4082,9 @@ def css_calc(x, left: float, right: float, align: str, color: str | list | tuple
return ret

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

if align == "mid":
Expand Down
53 changes: 52 additions & 1 deletion pandas/tests/io/formats/style/test_bar.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import io

import numpy as np
import pytest

from pandas import DataFrame
from pandas import (
NA,
DataFrame,
read_csv,
)

pytest.importorskip("jinja2")

Expand Down Expand Up @@ -305,3 +311,48 @@ def test_bar_value_error_raises():
msg = r"`height` must be a value in \[0, 100\]"
with pytest.raises(ValueError, match=msg):
df.style.bar(height=200).to_html()


def test_bar_color_and_cmap_error_raises():
df = DataFrame({"A": [1, 2, 3, 4]})
msg = "`color` and `cmap` cannot both be given"
# Test that providing both color and cmap raises a ValueError
with pytest.raises(ValueError, match=msg):
df.style.bar(color="#d65f5f", cmap="viridis").to_html()


def test_bar_invalid_color_type_error_raises():
df = DataFrame({"A": [1, 2, 3, 4]})
msg = (
r"`color` must be string or list or tuple of 2 strings,"
r"\(eg: color=\['#d65f5f', '#5fba7d'\]\)"
)
# Test that providing an invalid color type raises a ValueError
with pytest.raises(ValueError, match=msg):
df.style.bar(color=123).to_html()

# Test that providing a color list with more than two elements raises a ValueError
with pytest.raises(ValueError, match=msg):
df.style.bar(color=["#d65f5f", "#5fba7d", "#abcdef"]).to_html()


def test_styler_bar_with_NA_values():
df1 = DataFrame({"A": [1, 2, NA, 4]})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you test arrow types here per the original issue?

Copy link
Contributor Author

@ccccjone ccccjone Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mroeschke , thank you for your response. I tried to add pyarrow into the test like the origin issue, but encountered a DeprecationWarning when using engine="pyarrow".

I noticed two PRs related to pyarrow issue, #55637 and #55576 , where several tests were marked as xfail due to parsing or type problems with pyarrow.

However, the test can be passed without specifying the engine, and I updated this test in my recent commit, although pyarrow maybe not suitable for this unit test.

def test_style_with_pyarrow_NA_values():
    data = """name,age,test1,test2,teacher
        Adam,15,95.0,80,Ashby
        Bob,16,81.0,82,Ashby
        Dave,16,89.0,84,Jones
        Fred,15,,88,Jones"""
    df = read_csv(io.StringIO(data), dtype_backend="pyarrow")
    expected_substring = "style type="
    html_output = df.style.bar(subset="test1").to_html()
    assert expected_substring in html_output

Look forward to your advice. Thank you!

df2 = DataFrame([[NA, NA], [NA, NA]])
expected_substring = "style type="
html_output1 = df1.style.bar(subset="A").to_html()
html_output2 = df2.style.bar(align="left", axis=None).to_html()
assert expected_substring in html_output1
assert expected_substring in html_output2


def test_style_bar_with_pyarrow_NA_values():
data = """name,age,test1,test2,teacher
Adam,15,95.0,80,Ashby
Bob,16,81.0,82,Ashby
Dave,16,89.0,84,Jones
Fred,15,,88,Jones"""
df = read_csv(io.StringIO(data), dtype_backend="pyarrow")
expected_substring = "style type="
html_output = df.style.bar(subset="test1").to_html()
assert expected_substring in html_output