From 8988e6cc6ac59e1a1d3e63b6d54f335b3fd00f2b Mon Sep 17 00:00:00 2001 From: Corban Date: Mon, 18 Nov 2024 20:55:24 +0400 Subject: [PATCH 01/11] fix to_latex for multiindex --- doc/source/whatsnew/v2.3.0.rst | 2 + pandas/io/formats/style_render.py | 2 + pandas/tests/io/formats/test_to_latex.py | 82 ++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/doc/source/whatsnew/v2.3.0.rst b/doc/source/whatsnew/v2.3.0.rst index b107a5d3ba100..dcff8d86328cd 100644 --- a/doc/source/whatsnew/v2.3.0.rst +++ b/doc/source/whatsnew/v2.3.0.rst @@ -48,6 +48,8 @@ These are bug fixes that might have notable behavior changes. .. _whatsnew_230.notable_bug_fixes.notable_bug_fix1: +- The `to_latex` is now fixed for hidden multiindex dataframes (:issue:`52218`) + notable_bug_fix1 ^^^^^^^^^^^^^^^^ diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index ecfe3de10c829..396057137310e 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -869,6 +869,8 @@ def _translate_latex(self, d: dict, clines: str | None) -> None: """ index_levels = self.index.nlevels visible_index_level_n = index_levels - sum(self.hide_index_) + if visible_index_level_n == 0: + visible_index_level_n = 1 d["head"] = [ [ {**col, "cellstyle": self.ctx_columns[r, c - visible_index_level_n]} diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 1de53993fe646..721abb50b0898 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -1405,3 +1405,85 @@ def test_to_latex_multiindex_multirow(self): """ ) assert result == expected + + def test_to_latex_multiindex_format_single_index_hidden(self): + # GH 52218 + df = pd.DataFrame({ + "A": [1, 2], + "B": [4, 5], + }) + result = ( + df.style.hide(axis="index") + .map_index(lambda v: "textbf:--rwrap;", axis="columns") + .to_latex() + ) + expected = _dedent(r""" + \begin{tabular}{rr} + \textbf{A} & \textbf{B} \\ + 1 & 4 \\ + 2 & 5 \\ + \end{tabular} + """ + ) + assert result == expected + + def test_to_latex_multiindex_format_triple_index_two_hidden(self): + # GH 52218 + arrays = [ + ["A", "A", "B", "B"], + ["one", "two", "one", "two"], + ["x", "x", "y", "y"], + ] + index = pd.MultiIndex.from_arrays(arrays, names=["Level 0", "Level 1", "Level 2"]) + df = pd.DataFrame( + [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], + index=index, + columns=["C1", "C2", "C3"] + ) + result = ( + df.style.hide(axis="index", level=[0, 1]) + .map_index(lambda v: "textbf:--rwrap;", axis="columns") + .to_latex() + ) + expected = _dedent(r""" + \begin{tabular}{lrrr} + & \textbf{C1} & \textbf{C2} & \textbf{C3} \\ + Level 2 & & & \\ + x & 0 & 0 & 0 \\ + x & 0 & 0 & 0 \\ + y & 0 & 0 & 0 \\ + y & 0 & 0 & 0 \\ + \end{tabular} + """ + ) + assert result == expected + + def test_to_latex_multiindex_format_triple_index_all_hidden(self): + # GH 52218 + arrays = [ + ["A", "A", "B", "B"], + ["one", "two", "one", "two"], + ["x", "x", "y", "y"], + ] + index = pd.MultiIndex.from_arrays(arrays, names=["Level 0", "Level 1", "Level 2"]) + df = pd.DataFrame( + [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], + index=index, + columns=["C1", "C2", "C3"] + ) + result = ( + df.style.hide(axis="index", level=[0, 1, 2]) + .map_index(lambda v: "textbf:--rwrap;", axis="columns") + .to_latex() + ) + expected = _dedent(r""" + \begin{tabular}{rrr} + \textbf{C1} & \textbf{C2} & \textbf{C3} \\ + 0 & 0 & 0 \\ + 0 & 0 & 0 \\ + 0 & 0 & 0 \\ + 0 & 0 & 0 \\ + \end{tabular} + """ + ) + assert result == expected \ No newline at end of file From bfeb2471a69bec5757fbb5599bba4fdf3222d83a Mon Sep 17 00:00:00 2001 From: Animcogn Date: Mon, 18 Nov 2024 21:19:50 +0400 Subject: [PATCH 02/11] add newline --- pandas/tests/io/formats/test_to_latex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 721abb50b0898..88446288defc8 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -1486,4 +1486,4 @@ def test_to_latex_multiindex_format_triple_index_all_hidden(self): \end{tabular} """ ) - assert result == expected \ No newline at end of file + assert result == expected From eb037627a0d07da5798aade59a9506a5c6e2e1ca Mon Sep 17 00:00:00 2001 From: Corban Date: Mon, 18 Nov 2024 18:09:11 +0000 Subject: [PATCH 03/11] fix styling --- pandas/tests/io/formats/test_to_latex.py | 43 +++++++++++++----------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 88446288defc8..8d46442611719 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -1408,10 +1408,12 @@ def test_to_latex_multiindex_multirow(self): def test_to_latex_multiindex_format_single_index_hidden(self): # GH 52218 - df = pd.DataFrame({ - "A": [1, 2], - "B": [4, 5], - }) + df = DataFrame( + { + "A": [1, 2], + "B": [4, 5], + } + ) result = ( df.style.hide(axis="index") .map_index(lambda v: "textbf:--rwrap;", axis="columns") @@ -1423,8 +1425,7 @@ def test_to_latex_multiindex_format_single_index_hidden(self): 1 & 4 \\ 2 & 5 \\ \end{tabular} - """ - ) + """) assert result == expected def test_to_latex_multiindex_format_triple_index_two_hidden(self): @@ -1434,11 +1435,13 @@ def test_to_latex_multiindex_format_triple_index_two_hidden(self): ["one", "two", "one", "two"], ["x", "x", "y", "y"], ] - index = pd.MultiIndex.from_arrays(arrays, names=["Level 0", "Level 1", "Level 2"]) - df = pd.DataFrame( - [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], - index=index, - columns=["C1", "C2", "C3"] + index = pd.MultiIndex.from_arrays( + arrays, names=["Level 0", "Level 1", "Level 2"] + ) + df = DataFrame( + [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], + index=index, + columns=["C1", "C2", "C3"], ) result = ( df.style.hide(axis="index", level=[0, 1]) @@ -1454,8 +1457,7 @@ def test_to_latex_multiindex_format_triple_index_two_hidden(self): y & 0 & 0 & 0 \\ y & 0 & 0 & 0 \\ \end{tabular} - """ - ) + """) assert result == expected def test_to_latex_multiindex_format_triple_index_all_hidden(self): @@ -1465,11 +1467,13 @@ def test_to_latex_multiindex_format_triple_index_all_hidden(self): ["one", "two", "one", "two"], ["x", "x", "y", "y"], ] - index = pd.MultiIndex.from_arrays(arrays, names=["Level 0", "Level 1", "Level 2"]) - df = pd.DataFrame( - [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], - index=index, - columns=["C1", "C2", "C3"] + index = pd.MultiIndex.from_arrays( + arrays, names=["Level 0", "Level 1", "Level 2"] + ) + df = DataFrame( + [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], + index=index, + columns=["C1", "C2", "C3"], ) result = ( df.style.hide(axis="index", level=[0, 1, 2]) @@ -1484,6 +1488,5 @@ def test_to_latex_multiindex_format_triple_index_all_hidden(self): 0 & 0 & 0 \\ 0 & 0 & 0 \\ \end{tabular} - """ - ) + """) assert result == expected From a759e5f8a36f08fa473894af4ee2619ce6831708 Mon Sep 17 00:00:00 2001 From: Animcogn Date: Tue, 19 Nov 2024 19:24:41 +0400 Subject: [PATCH 04/11] Update v2.3.0.rst fix backticks --- doc/source/whatsnew/v2.3.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.3.0.rst b/doc/source/whatsnew/v2.3.0.rst index dcff8d86328cd..2cc650a5a3dc0 100644 --- a/doc/source/whatsnew/v2.3.0.rst +++ b/doc/source/whatsnew/v2.3.0.rst @@ -48,7 +48,7 @@ These are bug fixes that might have notable behavior changes. .. _whatsnew_230.notable_bug_fixes.notable_bug_fix1: -- The `to_latex` is now fixed for hidden multiindex dataframes (:issue:`52218`) +- The ``to_latex`` function is now fixed for hidden multiindex dataframes (:issue:`52218`) notable_bug_fix1 ^^^^^^^^^^^^^^^^ From a505fe9630189e1c51c5d853d22741cfac16aa64 Mon Sep 17 00:00:00 2001 From: Animcogn Date: Tue, 19 Nov 2024 23:20:27 +0400 Subject: [PATCH 05/11] update description. --- doc/source/whatsnew/v2.3.0.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v2.3.0.rst b/doc/source/whatsnew/v2.3.0.rst index 2cc650a5a3dc0..4e77f34026bb3 100644 --- a/doc/source/whatsnew/v2.3.0.rst +++ b/doc/source/whatsnew/v2.3.0.rst @@ -48,8 +48,6 @@ These are bug fixes that might have notable behavior changes. .. _whatsnew_230.notable_bug_fixes.notable_bug_fix1: -- The ``to_latex`` function is now fixed for hidden multiindex dataframes (:issue:`52218`) - notable_bug_fix1 ^^^^^^^^^^^^^^^^ @@ -75,6 +73,8 @@ Performance improvements Bug fixes ~~~~~~~~~ +- The ``to_latex`` styling of column headers when combined with a hidden index or hidden index-levels is fixed. + Categorical ^^^^^^^^^^^ - From 93802f27d647a0471232bf0f96788673935b60a2 Mon Sep 17 00:00:00 2001 From: Animcogn Date: Wed, 20 Nov 2024 09:39:16 +0400 Subject: [PATCH 06/11] Apply suggested fix Co-authored-by: JHM Darbyshire <24256554+attack68@users.noreply.github.com> --- pandas/io/formats/style_render.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 396057137310e..2682549659739 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -868,9 +868,9 @@ def _translate_latex(self, d: dict, clines: str | None) -> None: or multirow sparsification (so that \multirow and \multicol work correctly). """ index_levels = self.index.nlevels - visible_index_level_n = index_levels - sum(self.hide_index_) - if visible_index_level_n == 0: - visible_index_level_n = 1 + # d["head"] will contain at least one column relating to the index, + # it will be marked as `is_visible`: False if all levels are hidden + visible_index_level_n = max(1, index_levels - sum(self.hide_index_)) d["head"] = [ [ {**col, "cellstyle": self.ctx_columns[r, c - visible_index_level_n]} From 1623424758891661389d6bd8553be01b0412780b Mon Sep 17 00:00:00 2001 From: Animcogn Date: Wed, 20 Nov 2024 12:32:46 -0700 Subject: [PATCH 07/11] move to v.3 --- doc/source/whatsnew/v2.3.0.rst | 2 -- doc/source/whatsnew/v3.0.0.rst | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v2.3.0.rst b/doc/source/whatsnew/v2.3.0.rst index 4e77f34026bb3..b107a5d3ba100 100644 --- a/doc/source/whatsnew/v2.3.0.rst +++ b/doc/source/whatsnew/v2.3.0.rst @@ -73,8 +73,6 @@ Performance improvements Bug fixes ~~~~~~~~~ -- The ``to_latex`` styling of column headers when combined with a hidden index or hidden index-levels is fixed. - Categorical ^^^^^^^^^^^ - diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 7da2f968b900b..4047f53384d81 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -762,7 +762,9 @@ ExtensionArray Styler ^^^^^^ -- + +- Bug in :method:`Styler.to_latex` where styling column headers when combined with a hidden index or hidden index-levels is fixed. +- Other ^^^^^ From 07e02771066c3b1d2e8619b1ad8c45a35e1dbeb8 Mon Sep 17 00:00:00 2001 From: Animcogn Date: Wed, 20 Nov 2024 23:33:09 +0400 Subject: [PATCH 08/11] Update pandas/io/formats/style_render.py Co-authored-by: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> --- pandas/io/formats/style_render.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 2682549659739..c0f0608f1ab32 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -868,8 +868,7 @@ def _translate_latex(self, d: dict, clines: str | None) -> None: or multirow sparsification (so that \multirow and \multicol work correctly). """ index_levels = self.index.nlevels - # d["head"] will contain at least one column relating to the index, - # it will be marked as `is_visible`: False if all levels are hidden + # GH 52218 visible_index_level_n = max(1, index_levels - sum(self.hide_index_)) d["head"] = [ [ From 7983aa41de5e01447a72834d868a57dd391a355e Mon Sep 17 00:00:00 2001 From: Animcogn Date: Wed, 20 Nov 2024 23:34:00 +0400 Subject: [PATCH 09/11] spacing --- doc/source/whatsnew/v3.0.0.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 4047f53384d81..050b630eedbd9 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -762,7 +762,6 @@ ExtensionArray Styler ^^^^^^ - - Bug in :method:`Styler.to_latex` where styling column headers when combined with a hidden index or hidden index-levels is fixed. - From ee7183b74bef0db1e29bf28f5c3f0cd1680be327 Mon Sep 17 00:00:00 2001 From: Corban Date: Thu, 21 Nov 2024 06:11:13 +0000 Subject: [PATCH 10/11] fix whitespace --- doc/source/whatsnew/v3.0.0.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 050b630eedbd9..29474f1f1ce59 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -763,7 +763,6 @@ ExtensionArray Styler ^^^^^^ - Bug in :method:`Styler.to_latex` where styling column headers when combined with a hidden index or hidden index-levels is fixed. -- Other ^^^^^ From 63bd28c08c122c8aa9fedb30f358278ec32f6ce6 Mon Sep 17 00:00:00 2001 From: Corban Date: Thu, 21 Nov 2024 08:12:12 +0000 Subject: [PATCH 11/11] fix method name --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 29474f1f1ce59..07c71a91f611a 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -762,7 +762,7 @@ ExtensionArray Styler ^^^^^^ -- Bug in :method:`Styler.to_latex` where styling column headers when combined with a hidden index or hidden index-levels is fixed. +- Bug in :meth:`Styler.to_latex` where styling column headers when combined with a hidden index or hidden index-levels is fixed. Other ^^^^^