From 508acf74917e4ac2d339e9957f3b72b0b0962c43 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Mon, 27 Sep 2021 22:31:48 +0200 Subject: [PATCH 1/5] deprecate and change tests --- doc/source/reference/style.rst | 3 +- pandas/io/formats/style.py | 281 ++++++++---------- pandas/tests/io/formats/style/test_html.py | 12 +- .../tests/io/formats/style/test_non_unique.py | 2 +- pandas/tests/io/formats/style/test_style.py | 52 ++-- .../tests/io/formats/style/test_to_latex.py | 4 +- 6 files changed, 166 insertions(+), 188 deletions(-) diff --git a/doc/source/reference/style.rst b/doc/source/reference/style.rst index e67813084e389..a739993e4d376 100644 --- a/doc/source/reference/style.rst +++ b/doc/source/reference/style.rst @@ -40,8 +40,7 @@ Style application Styler.applymap_index Styler.format Styler.format_index - Styler.hide_index - Styler.hide_columns + Styler.hide Styler.set_td_classes Styler.set_table_styles Styler.set_table_attributes diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 67f92c4a67e14..1857ac5084f5a 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -2112,6 +2112,9 @@ def hide_index( .. versionchanged:: 1.3.0 + .. deprecated:: 1.4.0 + This method should be replaced by ``hide(axis="columns", **kwargs)`` + Parameters ---------- subset : label, array-like, IndexSlice, optional @@ -2135,99 +2138,14 @@ def hide_index( See Also -------- - Styler.hide_columns: Hide the entire column headers row, or specific columns. - - Examples - -------- - Simple application hiding specific rows: - - >>> df = pd.DataFrame([[1,2], [3,4], [5,6]], index=["a", "b", "c"]) - >>> df.style.hide_index(["a", "b"]) # doctest: +SKIP - 0 1 - c 5 6 - - Hide the index and retain the data values: - - >>> midx = pd.MultiIndex.from_product([["x", "y"], ["a", "b", "c"]]) - >>> df = pd.DataFrame(np.random.randn(6,6), index=midx, columns=midx) - >>> df.style.format("{:.1f}").hide_index() # doctest: +SKIP - x y - a b c a b c - 0.1 0.0 0.4 1.3 0.6 -1.4 - 0.7 1.0 1.3 1.5 -0.0 -0.2 - 1.4 -0.8 1.6 -0.2 -0.4 -0.3 - 0.4 1.0 -0.2 -0.8 -1.2 1.1 - -0.6 1.2 1.8 1.9 0.3 0.3 - 0.8 0.5 -0.3 1.2 2.2 -0.8 - - Hide specific rows but retain the index: - - >>> df.style.format("{:.1f}").hide_index(subset=(slice(None), ["a", "c"])) - ... # doctest: +SKIP - x y - a b c a b c - x b 0.7 1.0 1.3 1.5 -0.0 -0.2 - y b -0.6 1.2 1.8 1.9 0.3 0.3 - - Hide specific rows and the index: - - >>> df.style.format("{:.1f}").hide_index( - ... subset=(slice(None), ["a", "c"])).hide_index() # doctest: +SKIP - x y - a b c a b c - 0.7 1.0 1.3 1.5 -0.0 -0.2 - -0.6 1.2 1.8 1.9 0.3 0.3 - - Hide a specific level: - - >>> df.style.format("{:,.1f}").hide_index(level=1) # doctest: +SKIP - x y - a b c a b c - x 0.1 0.0 0.4 1.3 0.6 -1.4 - 0.7 1.0 1.3 1.5 -0.0 -0.2 - 1.4 -0.8 1.6 -0.2 -0.4 -0.3 - y 0.4 1.0 -0.2 -0.8 -1.2 1.1 - -0.6 1.2 1.8 1.9 0.3 0.3 - 0.8 0.5 -0.3 1.2 2.2 -0.8 - - Hiding just the index level names: - - >>> df.index.names = ["lev0", "lev1"] - >>> df.style.format("{:,.1f}").hide_index(names=True) # doctest: +SKIP - x y - a b c a b c - x a 0.1 0.0 0.4 1.3 0.6 -1.4 - b 0.7 1.0 1.3 1.5 -0.0 -0.2 - c 1.4 -0.8 1.6 -0.2 -0.4 -0.3 - y a 0.4 1.0 -0.2 -0.8 -1.2 1.1 - b -0.6 1.2 1.8 1.9 0.3 0.3 - c 0.8 0.5 -0.3 1.2 2.2 -0.8 + Styler.hide: Hide the entire index / columns, or specific rows / columns. """ - if level is not None and subset is not None: - raise ValueError("`subset` and `level` cannot be passed simultaneously") - - if subset is None: - if level is None and names: - # this combination implies user shows the index and hides just names - self.hide_index_names = True - return self - - levels_ = refactor_levels(level, self.index) - self.hide_index_ = [ - True if lev in levels_ else False for lev in range(self.index.nlevels) - ] - else: - subset_ = IndexSlice[subset, :] # new var so mypy reads not Optional - subset = non_reducing_slice(subset_) - hide = self.data.loc[subset] - hrows = self.index.get_indexer_for(hide.index) - # error: Incompatible types in assignment (expression has type - # "ndarray", variable has type "Sequence[int]") - self.hidden_rows = hrows # type: ignore[assignment] - - if names: - self.hide_index_names = True - return self + warnings.warn( + "this method is deprecated in favour of `Styler.hide(axis='index')`", + FutureWarning, + stacklevel=2, + ) + return self.hide(axis=0, level=level, subset=subset, names=names) def hide_columns( self, @@ -2247,6 +2165,9 @@ def hide_columns( .. versionchanged:: 1.3.0 + ..deprecated:: 1.4.0 + This method should be replaced by ``hide(axis="columns", **kwargs)`` + Parameters ---------- subset : label, array-like, IndexSlice, optional @@ -2270,70 +2191,114 @@ def hide_columns( See Also -------- - Styler.hide_index: Hide the entire index, or specific keys in the index. + Styler.hide: Hide the entire index / columns, or specific rows / columns. + """ + warnings.warn( + "this method is deprecated in favour of `Styler.hide(axis='columns')`", + FutureWarning, + stacklevel=2, + ) + return self.hide(axis=1, level=level, subset=subset, names=names) + + def hide( + self, + subset: Subset | None = None, + axis: Axis = 0, + level: Level | list[Level] | None = None, + names: bool = False, + ) -> Styler: + """ + Hide the entire index / column headers, or specific rows / columns from display. + + This method has multiple functionality (see examples): + + - if ``subset`` is ``None`` then the entire index / columns headers (or + specified levels) are hidden whilst displaying all data-values, as well + as levels names. + - if ``subset`` is ``None``, but ``names`` is *True* then just the level names + for the given ``axis`` are hidden but the labels will remain. + - if a ``subset`` is given then those specific labels along the given + ``axis`` will be hidden whilst the index / column headers remain visible. + + .. versionadded:: 1.4.0 + + Parameters + ---------- + subset : label, array-like, IndexSlice, optional + A valid 1d input or single key along the axis within + `DataFrame.loc[, :]` or `DataFrame.loc[:, ]` depending + upon ``axis``, to limit ``data`` to select hidden rows / columns. + axis : {"index", 0, "columns", 1} + Apply to the index or columns. + level : int, str, list + The level(s) to hide in a MultiIndex if hiding the entire index / column + headers. Cannot be used simultaneously with ``subset``. + names : bool + Whether to hide the level name(s) of the index / columns headers in the case + it (or at least one the levels) remains visible. + + Returns + ------- + self : Styler Examples -------- - Simple application hiding specific columns: + Simple application hiding specific rows: - >>> df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=["a", "b", "c"]) - >>> df.style.hide_columns(["a", "b"]) # doctest: +SKIP - c - 0 3 - 1 6 + >>> df = pd.DataFrame([[1,2], [3,4], [5,6]], index=["a", "b", "c"]) + >>> df.style.hide(["a", "b"]) # doctest: +SKIP + 0 1 + c 5 6 - Hide column headers and retain the data values: + Hide the index and retain the data values: >>> midx = pd.MultiIndex.from_product([["x", "y"], ["a", "b", "c"]]) >>> df = pd.DataFrame(np.random.randn(6,6), index=midx, columns=midx) - >>> df.style.format("{:.1f}").hide_columns() # doctest: +SKIP - x a 0.1 0.0 0.4 1.3 0.6 -1.4 - b 0.7 1.0 1.3 1.5 -0.0 -0.2 - c 1.4 -0.8 1.6 -0.2 -0.4 -0.3 - y a 0.4 1.0 -0.2 -0.8 -1.2 1.1 - b -0.6 1.2 1.8 1.9 0.3 0.3 - c 0.8 0.5 -0.3 1.2 2.2 -0.8 + >>> df.style.format("{:.1f}").hide() # doctest: +SKIP + x y + a b c a b c + 0.1 0.0 0.4 1.3 0.6 -1.4 + 0.7 1.0 1.3 1.5 -0.0 -0.2 + 1.4 -0.8 1.6 -0.2 -0.4 -0.3 + 0.4 1.0 -0.2 -0.8 -1.2 1.1 + -0.6 1.2 1.8 1.9 0.3 0.3 + 0.8 0.5 -0.3 1.2 2.2 -0.8 - Hide specific columns but retain the column headers: + Hide specific rows but retain the index: - >>> df.style.format("{:.1f}").hide_columns(subset=(slice(None), ["a", "c"])) + >>> df.style.format("{:.1f}").hide(subset=(slice(None), ["a", "c"])) ... # doctest: +SKIP - x y - b b - x a 0.0 0.6 - b 1.0 -0.0 - c -0.8 -0.4 - y a 1.0 -1.2 - b 1.2 0.3 - c 0.5 2.2 - - Hide specific columns and the column headers: - - >>> df.style.format("{:.1f}").hide_columns( - ... subset=(slice(None), ["a", "c"])).hide_columns() # doctest: +SKIP - x a 0.0 0.6 - b 1.0 -0.0 - c -0.8 -0.4 - y a 1.0 -1.2 - b 1.2 0.3 - c 0.5 2.2 + x y + a b c a b c + x b 0.7 1.0 1.3 1.5 -0.0 -0.2 + y b -0.6 1.2 1.8 1.9 0.3 0.3 + + Hide specific rows and the index: + + >>> df.style.format("{:.1f}").hide( + ... subset=(slice(None), ["a", "c"])).hide() # doctest: +SKIP + x y + a b c a b c + 0.7 1.0 1.3 1.5 -0.0 -0.2 + -0.6 1.2 1.8 1.9 0.3 0.3 Hide a specific level: - >>> df.style.format("{:.1f}").hide_columns(level=1) # doctest: +SKIP - x y - x a 0.1 0.0 0.4 1.3 0.6 -1.4 - b 0.7 1.0 1.3 1.5 -0.0 -0.2 - c 1.4 -0.8 1.6 -0.2 -0.4 -0.3 - y a 0.4 1.0 -0.2 -0.8 -1.2 1.1 - b -0.6 1.2 1.8 1.9 0.3 0.3 - c 0.8 0.5 -0.3 1.2 2.2 -0.8 + >>> df.style.format("{:,.1f}").hide(level=1) # doctest: +SKIP + x y + a b c a b c + x 0.1 0.0 0.4 1.3 0.6 -1.4 + 0.7 1.0 1.3 1.5 -0.0 -0.2 + 1.4 -0.8 1.6 -0.2 -0.4 -0.3 + y 0.4 1.0 -0.2 -0.8 -1.2 1.1 + -0.6 1.2 1.8 1.9 0.3 0.3 + 0.8 0.5 -0.3 1.2 2.2 -0.8 - Hiding just the column level names: + Hiding just the index level names: - >>> df.columns.names = ["lev0", "lev1"] - >>> df.style.format("{:.1f").hide_columns(names=True) # doctest: +SKIP - x y + >>> df.index.names = ["lev0", "lev1"] + >>> df.style.format("{:,.1f}").hide(names=True) # doctest: +SKIP + x y a b c a b c x a 0.1 0.0 0.4 1.3 0.6 -1.4 b 0.7 1.0 1.3 1.5 -0.0 -0.2 @@ -2341,31 +2306,47 @@ def hide_columns( y a 0.4 1.0 -0.2 -0.8 -1.2 1.1 b -0.6 1.2 1.8 1.9 0.3 0.3 c 0.8 0.5 -0.3 1.2 2.2 -0.8 + + Examples all produce equivalently transposed effects with ``axis="columns"``. """ + axis = self.data._get_axis_number(axis) + if axis == 0: + obj, objs, alt = "index", "index", "rows" + else: + obj, objs, alt = "column", "columns", "columns" + if level is not None and subset is not None: raise ValueError("`subset` and `level` cannot be passed simultaneously") if subset is None: if level is None and names: - # this combination implies user shows the column headers but hides names - self.hide_column_names = True + # this combination implies user shows the index and hides just names + setattr(self, f"hide_{obj}_names", True) return self - levels_ = refactor_levels(level, self.columns) - self.hide_columns_ = [ - True if lev in levels_ else False for lev in range(self.columns.nlevels) - ] + levels_ = refactor_levels(level, getattr(self, objs)) + setattr( + self, + f"hide_{objs}_", + [ + True if lev in levels_ else False + for lev in range(getattr(self, objs).nlevels) + ], + ) else: - subset_ = IndexSlice[:, subset] # new var so mypy reads not Optional + if axis == 0: + subset_ = IndexSlice[subset, :] # new var so mypy reads not Optional + else: + subset_ = IndexSlice[:, subset] # new var so mypy reads not Optional subset = non_reducing_slice(subset_) hide = self.data.loc[subset] - hcols = self.columns.get_indexer_for(hide.columns) + h_els = getattr(self, objs).get_indexer_for(getattr(hide, objs)) # error: Incompatible types in assignment (expression has type # "ndarray", variable has type "Sequence[int]") - self.hidden_columns = hcols # type: ignore[assignment] + setattr(self, f"hidden_{alt}", h_els) # type: ignore[assignment] if names: - self.hide_column_names = True + setattr(self, f"hide_{obj}_names", True) return self # ----------------------------------------------------------------------- diff --git a/pandas/tests/io/formats/style/test_html.py b/pandas/tests/io/formats/style/test_html.py index b37edf1c09cd1..b18c97230434b 100644 --- a/pandas/tests/io/formats/style/test_html.py +++ b/pandas/tests/io/formats/style/test_html.py @@ -474,8 +474,8 @@ def test_include_css_style_rules_only_for_visible_cells(styler_mi): result = ( styler_mi.set_uuid("") .applymap(lambda v: "color: blue;") - .hide_columns(styler_mi.data.columns[1:]) - .hide_index(styler_mi.data.index[1:]) + .hide(styler_mi.data.columns[1:], axis="columns") + .hide(styler_mi.data.index[1:], axis="index") .to_html() ) expected_styles = dedent( @@ -495,8 +495,8 @@ def test_include_css_style_rules_only_for_visible_index_labels(styler_mi): result = ( styler_mi.set_uuid("") .applymap_index(lambda v: "color: blue;", axis="index") - .hide_columns(styler_mi.data.columns) - .hide_index(styler_mi.data.index[1:]) + .hide(styler_mi.data.columns, axis="columns") + .hide(styler_mi.data.index[1:], axis="index") .to_html() ) expected_styles = dedent( @@ -516,8 +516,8 @@ def test_include_css_style_rules_only_for_visible_column_labels(styler_mi): result = ( styler_mi.set_uuid("") .applymap_index(lambda v: "color: blue;", axis="columns") - .hide_columns(styler_mi.data.columns[1:]) - .hide_index(styler_mi.data.index) + .hide(styler_mi.data.columns[1:], axis="columns") + .hide(styler_mi.data.index, axis="index") .to_html() ) expected_styles = dedent( diff --git a/pandas/tests/io/formats/style/test_non_unique.py b/pandas/tests/io/formats/style/test_non_unique.py index 608f3d9cbd441..b719bf3372038 100644 --- a/pandas/tests/io/formats/style/test_non_unique.py +++ b/pandas/tests/io/formats/style/test_non_unique.py @@ -110,7 +110,7 @@ def test_set_td_classes_non_unique_raises(styler): def test_hide_columns_non_unique(styler): - ctx = styler.hide_columns(["d"])._translate(True, True) + ctx = styler.hide(["d"], axis="columns")._translate(True, True) assert ctx["head"][0][1]["display_value"] == "c" assert ctx["head"][0][1]["is_visible"] is True diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 6a09018c5b20b..bae5173aaa992 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -46,12 +46,10 @@ def mi_styler_comp(mi_styler): mi_styler.uuid = "abcde" mi_styler.set_caption("capt") mi_styler.set_table_styles([{"selector": "a", "props": "a:v;"}]) - mi_styler.hide_columns() - mi_styler.hide_columns([("c0", "c1_a")]) - mi_styler.hide_columns(names=True) - mi_styler.hide_index() - mi_styler.hide_index([("i0", "i1_a")]) - mi_styler.hide_index(names=True) + mi_styler.hide(axis="columns") + mi_styler.hide([("c0", "c1_a")], axis="columns", names=True) + mi_styler.hide(axis="index") + mi_styler.hide([("i0", "i1_a")], axis="index", names=True) mi_styler.set_table_attributes('class="box"') mi_styler.format(na_rep="MISSING", precision=3) mi_styler.format_index(precision=2, axis=0) @@ -326,17 +324,17 @@ def test_clear(mi_styler_comp): def test_hide_raises(mi_styler): msg = "`subset` and `level` cannot be passed simultaneously" with pytest.raises(ValueError, match=msg): - mi_styler.hide_index(subset="something", level="something else") + mi_styler.hide(axis="index", subset="something", level="something else") msg = "`level` must be of type `int`, `str` or list of such" with pytest.raises(ValueError, match=msg): - mi_styler.hide_index(level={"bad": 1, "type": 2}) + mi_styler.hide(axis="index", level={"bad": 1, "type": 2}) @pytest.mark.parametrize("level", [1, "one", [1], ["one"]]) def test_hide_index_level(mi_styler, level): mi_styler.index.names, mi_styler.columns.names = ["zero", "one"], ["zero", "one"] - ctx = mi_styler.hide_index(level=level)._translate(False, True) + ctx = mi_styler.hide(axis="index", level=level)._translate(False, True) assert len(ctx["head"][0]) == 3 assert len(ctx["head"][1]) == 3 assert len(ctx["head"][2]) == 4 @@ -355,7 +353,7 @@ def test_hide_columns_level(mi_styler, level, names): mi_styler.columns.names = ["zero", "one"] if names: mi_styler.index.names = ["zero", "one"] - ctx = mi_styler.hide_columns(level=level)._translate(True, False) + ctx = mi_styler.hide(axis="columns", level=level)._translate(True, False) assert len(ctx["head"]) == (2 if names else 1) @@ -1087,11 +1085,11 @@ def test_mi_sparse_column_names(self): assert head == expected def test_hide_column_headers(self): - ctx = self.styler.hide_columns()._translate(True, True) + ctx = self.styler.hide(axis="columns")._translate(True, True) assert len(ctx["head"]) == 0 # no header entries with an unnamed index self.df.index.name = "some_name" - ctx = self.df.style.hide_columns()._translate(True, True) + ctx = self.df.style.hide(axis="columns")._translate(True, True) assert len(ctx["head"]) == 1 # index names still visible, changed in #42101, reverted in 43404 @@ -1101,7 +1099,7 @@ def test_hide_single_index(self): ctx = self.df.style._translate(True, True) assert ctx["body"][0][0]["is_visible"] assert ctx["head"][0][0]["is_visible"] - ctx2 = self.df.style.hide_index()._translate(True, True) + ctx2 = self.df.style.hide(axis="index")._translate(True, True) assert not ctx2["body"][0][0]["is_visible"] assert not ctx2["head"][0][0]["is_visible"] @@ -1111,7 +1109,7 @@ def test_hide_single_index(self): assert len(ctx3["head"]) == 2 # 2 header levels assert ctx3["head"][0][0]["is_visible"] - ctx4 = self.df.set_index("A").style.hide_index()._translate(True, True) + ctx4 = self.df.set_index("A").style.hide(axis="index")._translate(True, True) assert not ctx4["body"][0][0]["is_visible"] assert len(ctx4["head"]) == 1 # only 1 header levels assert not ctx4["head"][0][0]["is_visible"] @@ -1131,7 +1129,7 @@ def test_hide_multiindex(self): # check for blank header rows assert len(ctx1["head"][0]) == 4 # two visible indexes and two data columns - ctx2 = df.style.hide_index()._translate(True, True) + ctx2 = df.style.hide(axis="index")._translate(True, True) # tests for 'a' and '0' assert not ctx2["body"][0][0]["is_visible"] assert not ctx2["body"][0][1]["is_visible"] @@ -1150,13 +1148,13 @@ def test_hide_columns_single_level(self): assert ctx["body"][0][1]["is_visible"] # col A, row 1 assert ctx["body"][1][2]["is_visible"] # col B, row 1 - ctx = self.df.style.hide_columns("A")._translate(True, True) + ctx = self.df.style.hide("A", axis="columns")._translate(True, True) assert not ctx["head"][0][1]["is_visible"] assert not ctx["body"][0][1]["is_visible"] # col A, row 1 assert ctx["body"][1][2]["is_visible"] # col B, row 1 # test hiding mulitiple columns - ctx = self.df.style.hide_columns(["A", "B"])._translate(True, True) + ctx = self.df.style.hide(["A", "B"], axis="columns")._translate(True, True) assert not ctx["head"][0][1]["is_visible"] assert not ctx["head"][0][2]["is_visible"] assert not ctx["body"][0][1]["is_visible"] # col A, row 1 @@ -1186,14 +1184,14 @@ def test_hide_columns_index_mult_levels(self): assert ctx["body"][1][3]["display_value"] == "4" # hide top column level, which hides both columns - ctx = df.style.hide_columns("b")._translate(True, True) + ctx = df.style.hide("b", axis="columns")._translate(True, True) assert not ctx["head"][0][2]["is_visible"] # b assert not ctx["head"][1][2]["is_visible"] # 0 assert not ctx["body"][1][2]["is_visible"] # 3 assert ctx["body"][0][0]["is_visible"] # index # hide first column only - ctx = df.style.hide_columns([("b", 0)])._translate(True, True) + ctx = df.style.hide([("b", 0)], axis="columns")._translate(True, True) assert not ctx["head"][0][2]["is_visible"] # b assert ctx["head"][0][3]["is_visible"] # b assert not ctx["head"][1][2]["is_visible"] # 0 @@ -1202,7 +1200,7 @@ def test_hide_columns_index_mult_levels(self): assert ctx["body"][1][3]["display_value"] == "4" # hide second column and index - ctx = df.style.hide_columns([("b", 1)]).hide_index()._translate(True, True) + ctx = df.style.hide([("b", 1)], axis=1).hide(axis=0)._translate(True, True) assert not ctx["body"][0][0]["is_visible"] # index assert len(ctx["head"][0]) == 3 assert ctx["head"][0][1]["is_visible"] # b @@ -1213,13 +1211,13 @@ def test_hide_columns_index_mult_levels(self): assert ctx["body"][1][2]["display_value"] == "3" # hide top row level, which hides both rows - ctx = df.style.hide_index("a")._translate(True, True) + ctx = df.style.hide("a", axis="index")._translate(True, True) for i in [0, 1, 2, 3]: assert not ctx["body"][0][i]["is_visible"] assert not ctx["body"][1][i]["is_visible"] # hide first row only - ctx = df.style.hide_index(("a", 0))._translate(True, True) + ctx = df.style.hide(("a", 0), axis="index")._translate(True, True) for i in [0, 1, 2, 3]: assert not ctx["body"][0][i]["is_visible"] assert ctx["body"][1][i]["is_visible"] @@ -1441,13 +1439,13 @@ def test_hidden_index_names(mi_df): ctx = mi_styler._translate(True, True) assert len(ctx["head"]) == 3 # 2 column index levels + 1 index names row - mi_styler.hide_index(names=True) + mi_styler.hide(axis="index", names=True) ctx = mi_styler._translate(True, True) assert len(ctx["head"]) == 2 # index names row is unparsed for i in range(4): assert ctx["body"][0][i]["is_visible"] # 2 index levels + 2 data values visible - mi_styler.hide_index(level=1) + mi_styler.hide(axis="index", level=1) ctx = mi_styler._translate(True, True) assert len(ctx["head"]) == 2 # index names row is still hidden assert ctx["body"][0][0]["is_visible"] is True @@ -1461,12 +1459,12 @@ def test_hidden_column_names(mi_df): assert ctx["head"][0][1]["display_value"] == "Lev0" assert ctx["head"][1][1]["display_value"] == "Lev1" - mi_styler.hide_columns(names=True) + mi_styler.hide(names=True, axis="columns") ctx = mi_styler._translate(True, True) assert ctx["head"][0][1]["display_value"] == " " assert ctx["head"][1][1]["display_value"] == " " - mi_styler.hide_columns(level=0) + mi_styler.hide(level=0, axis="columns") ctx = mi_styler._translate(True, True) assert len(ctx["head"]) == 1 # no index names and only one visible column headers assert ctx["head"][0][1]["display_value"] == " " @@ -1489,7 +1487,7 @@ def test_hiding_headers_over_axis_no_sparsify(axis): columns=midx if axis == "columns" else [0], ) - styler = getattr(df.style, f"hide_{axis}")((1, "a")) + styler = df.style.hide((1, "a"), axis=axis) ctx = styler._translate(False, False) if axis == "columns": # test column headers diff --git a/pandas/tests/io/formats/style/test_to_latex.py b/pandas/tests/io/formats/style/test_to_latex.py index a2e42efdacd89..ce54b48c7a6ee 100644 --- a/pandas/tests/io/formats/style/test_to_latex.py +++ b/pandas/tests/io/formats/style/test_to_latex.py @@ -360,7 +360,7 @@ def test_multiindex_columns_hidden(): s = df.style assert "{tabular}{lrrrr}" in s.to_latex() s.set_table_styles([]) # reset the position command - s.hide_columns([("A", 2)]) + s.hide([("A", 2)], axis="columns") assert "{tabular}{lrrr}" in s.to_latex() @@ -386,7 +386,7 @@ def test_sparse_options(df_ext, option, value): def test_hidden_index(styler): - styler.hide_index() + styler.hide(axis="index") expected = dedent( """\ \\begin{tabular}{rrl} From adb94dbb10f8b3c3fee9c51945d5c76356109019 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Sun, 24 Oct 2021 21:28:36 +0200 Subject: [PATCH 2/5] doc string edits --- pandas/io/formats/style.py | 68 ++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 70e4c3e03de2d..f0428d9343f7a 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -2338,16 +2338,6 @@ def hide( """ Hide the entire index / column headers, or specific rows / columns from display. - This method has multiple functionality (see examples): - - - if ``subset`` is ``None`` then the entire index / columns headers (or - specified levels) are hidden whilst displaying all data-values, as well - as levels names. - - if ``subset`` is ``None``, but ``names`` is *True* then just the level names - for the given ``axis`` are hidden but the labels will remain. - - if a ``subset`` is given then those specific labels along the given - ``axis`` will be hidden whilst the index / column headers remain visible. - .. versionadded:: 1.4.0 Parameters @@ -2369,6 +2359,56 @@ def hide( ------- self : Styler + Notes + ----- + This method has multiple functionality depending upon the combination + of the ``subset``, ``level`` and ``names`` arguments (see examples). The + ``axis`` argument is used only to control whether the method is applied to row + or column headers: + + .. list-table:: Argument combinations + :widths: 10 20 10 60 + :header-rows: 1 + + * - ``subset`` + - ``level`` + - ``names`` + - Effect + * - None + - None + - False + - The axis-Index is hidden entirely. + * - None + - None + - True + - Only the axis-Index names are hidden. + * - None + - Int, Str, List + - False + - Specified axis-MultiIndex levels are hidden entirely. + * - None + - Int, Str, List + - True + - Specified axis-MultiIndex levels are hidden entirely and the names of + remaining axis-MultiIndex levels. + * - Subset + - None + - False + - The specified data rows/columns are hidden, but the axis-Index itself, + and names, remain unchanged. + * - Subset + - None + - True + - The specified data rows/columns and axis-Index names are hidden, but + the axis-Index itself remains unchanged. + * - Subset + - Int, Str, List + - Boolean + - ValueError: cannot supply ``subset`` and ``level`` simultaneously. + + Note this method only hides the identifed elements so can be chained to hide + multiple elements in sequence. + Examples -------- Simple application hiding specific rows: @@ -2392,7 +2432,7 @@ def hide( -0.6 1.2 1.8 1.9 0.3 0.3 0.8 0.5 -0.3 1.2 2.2 -0.8 - Hide specific rows but retain the index: + Hide specific rows in a MultiIndex but retain the index: >>> df.style.format("{:.1f}").hide(subset=(slice(None), ["a", "c"])) ... # doctest: +SKIP @@ -2401,10 +2441,10 @@ def hide( x b 0.7 1.0 1.3 1.5 -0.0 -0.2 y b -0.6 1.2 1.8 1.9 0.3 0.3 - Hide specific rows and the index: + Hide specific rows and the index through chaining: - >>> df.style.format("{:.1f}").hide( - ... subset=(slice(None), ["a", "c"])).hide() # doctest: +SKIP + >>> df.style.format("{:.1f}").hide(subset=(slice(None), ["a", "c"])).hide() + ... # doctest: +SKIP x y a b c a b c 0.7 1.0 1.3 1.5 -0.0 -0.2 From 9d2d60b804b14b0be8a12ca925ff2e16c45de1b1 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Mon, 25 Oct 2021 18:35:10 +0200 Subject: [PATCH 3/5] mypy --- pandas/io/formats/style.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index f0428d9343f7a..d91c0bb54f8dc 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -2509,9 +2509,7 @@ def hide( subset = non_reducing_slice(subset_) hide = self.data.loc[subset] h_els = getattr(self, objs).get_indexer_for(getattr(hide, objs)) - # error: Incompatible types in assignment (expression has type - # "ndarray", variable has type "Sequence[int]") - setattr(self, f"hidden_{alt}", h_els) # type: ignore[assignment] + setattr(self, f"hidden_{alt}", h_els) if names: setattr(self, f"hide_{obj}_names", True) From 754987fa5e9decf244360edca11e269743bd0edd Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Mon, 25 Oct 2021 18:42:01 +0200 Subject: [PATCH 4/5] whats new --- doc/source/whatsnew/v1.4.0.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 7f6d2d247177e..25d2836d511b3 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -79,10 +79,11 @@ Styler - Keyword arguments ``level`` and ``names`` added to :meth:`.Styler.hide_index` and :meth:`.Styler.hide_columns` for additional control of visibility of MultiIndexes and index names (:issue:`25475`, :issue:`43404`, :issue:`43346`) - Global options have been extended to configure default ``Styler`` properties including formatting and encoding and mathjax options and LaTeX (:issue:`41395`) - Naive sparsification is now possible for LaTeX without the multirow package (:issue:`43369`) - - :meth:`Styler.to_html` omits CSSStyle rules for hidden table elements (:issue:`43619`) + - :meth:`.Styler.to_html` omits CSSStyle rules for hidden table elements (:issue:`43619`) - Custom CSS classes can now be directly specified without string replacement (:issue:`43686`) - Bug where row trimming failed to reflect hidden rows (:issue:`43703`) - Update and expand the export and use mechanics (:issue:`40675`) + - New method :meth:`.Styler.hide` added and deprecates :meth:`.Styler.hide_index` and :meth:`.Styler.hide_columns` (:issue:`43758`) Formerly Styler relied on ``display.html.use_mathjax``, which has now been replaced by ``styler.html.mathjax``. From 40eb5cf8eb82d208d51fcab6c62fa04e54748b22 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Sat, 30 Oct 2021 15:47:02 +0200 Subject: [PATCH 5/5] deprecation tests --- pandas/tests/io/formats/style/test_deprecated.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/tests/io/formats/style/test_deprecated.py b/pandas/tests/io/formats/style/test_deprecated.py index a582761d7bff7..9c96e3cf1ba81 100644 --- a/pandas/tests/io/formats/style/test_deprecated.py +++ b/pandas/tests/io/formats/style/test_deprecated.py @@ -20,6 +20,12 @@ def df(): return DataFrame({"A": [0, 1], "B": np.random.randn(2)}) +@pytest.mark.parametrize("axis", ["index", "columns"]) +def test_hide_index_columns(df, axis): + with tm.assert_produces_warning(FutureWarning): + getattr(df.style, "hide_" + axis)() + + def test_set_non_numeric_na(): # GH 21527 28358 df = DataFrame(