From ffbc621e087eea3bc191e152922bda1a974c5a51 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Thu, 19 Jan 2023 21:50:15 +0100 Subject: [PATCH 1/9] remove redundant latex options --- doc/source/whatsnew/v2.0.0.rst | 4 ++- pandas/core/config_init.py | 52 ---------------------------------- 2 files changed, 3 insertions(+), 53 deletions(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 7555c8b68a4f7..983fdd397cf61 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -465,7 +465,9 @@ The arguments signature is similar, albeit ``col_space`` has been removed since it is ignored by LaTeX engines. This render engine also requires ``jinja2`` as a dependency which needs to be installed, since rendering is based upon jinja2 templates. -The pandas options below are no longer used and will be removed in future releases. +The pandas latex options below are no longer used and have been removed. The generic +max rows and columns arguments remain but for this functionality should be replaced +by the Styler equivalents. The alternative options giving similar functionality are indicated below: - ``display.latex.escape``: replaced with ``styler.format.escape``, diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index da9e7de9821b1..fb4504edb67e7 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -210,13 +210,6 @@ def use_numba_cb(key) -> None: (default: False) """ -pc_latex_repr_doc = """ -: boolean - Whether to produce a latex DataFrame representation for jupyter - environments that support it. - (default: False) -""" - pc_table_schema_doc = """ : boolean Whether to publish a Table Schema representation for frontends @@ -292,41 +285,6 @@ def use_numba_cb(key) -> None: df.info() is called. Valid values True,False,'deep' """ -pc_latex_escape = """ -: bool - This specifies if the to_latex method of a Dataframe uses escapes special - characters. - Valid values: False,True -""" - -pc_latex_longtable = """ -:bool - This specifies if the to_latex method of a Dataframe uses the longtable - format. - Valid values: False,True -""" - -pc_latex_multicolumn = """ -: bool - This specifies if the to_latex method of a Dataframe uses multicolumns - to pretty-print MultiIndex columns. - Valid values: False,True -""" - -pc_latex_multicolumn_format = """ -: string - This specifies the format for multicolumn headers. - Can be surrounded with '|'. - Valid values: 'l', 'c', 'r', 'p{}' -""" - -pc_latex_multirow = """ -: bool - This specifies if the to_latex method of a Dataframe uses multirows - to pretty-print MultiIndex rows. - Valid values: False,True -""" - def table_schema_cb(key) -> None: from pandas.io.formats.printing import enable_data_resource_formatter @@ -425,16 +383,6 @@ def is_terminal() -> bool: cf.register_option( "unicode.ambiguous_as_wide", False, pc_east_asian_width_doc, validator=is_bool ) - cf.register_option("latex.repr", False, pc_latex_repr_doc, validator=is_bool) - cf.register_option("latex.escape", True, pc_latex_escape, validator=is_bool) - cf.register_option("latex.longtable", False, pc_latex_longtable, validator=is_bool) - cf.register_option( - "latex.multicolumn", True, pc_latex_multicolumn, validator=is_bool - ) - cf.register_option( - "latex.multicolumn_format", "l", pc_latex_multicolumn, validator=is_text - ) - cf.register_option("latex.multirow", False, pc_latex_multirow, validator=is_bool) cf.register_option( "html.table_schema", False, From 567f71d0159cde54a71061f2c6211a78b7a5fee0 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Fri, 20 Jan 2023 18:44:05 +0100 Subject: [PATCH 2/9] remove redundant latex options --- pandas/core/generic.py | 32 +++++++++++++++--------- pandas/tests/io/formats/test_to_latex.py | 16 ++++++------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 028fdacd7444e..2de93ee156663 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3263,12 +3263,15 @@ def to_latex( columns. By default, 'l' will be used for all columns except columns of numbers, which default to 'r'. longtable : bool, optional - By default, the value will be read from the pandas config - module. Use a longtable environment instead of tabular. Requires + Use a longtable environment instead of tabular. Requires adding a \usepackage{{longtable}} to your LaTeX preamble. + By default, the value will be read from the pandas config + module, and set to `True` if the option ``styler.latex.environment`` is + `"longtable"`. escape : bool, optional By default, the value will be read from the pandas config - module. When set to False prevents from escaping latex special + module and set to `True` if the option ``styler.format.escape`` is + `"latex"`. When set to False prevents from escaping latex special characters in column names. encoding : str, optional A string representing the encoding to use in the output file, @@ -3277,16 +3280,19 @@ def to_latex( Character recognized as decimal separator, e.g. ',' in Europe. multicolumn : bool, default True Use \multicolumn to enhance MultiIndex columns. - The default will be read from the config module. + The default will be read from the config module, and is set + as the option ``styler.sparse.columns``. multicolumn_format : str, default 'l' The alignment for multicolumns, similar to `column_format` - The default will be read from the config module. + The default will be read from the config module, and is set as the option + ``styler.latex.multicol_align``. multirow : bool, default False Use \multirow to enhance MultiIndex rows. Requires adding a \usepackage{{multirow}} to your LaTeX preamble. Will print centered labels (instead of top-aligned) across the contained rows, separating groups via clines. The default will be read - from the pandas config module. + from the pandas config module, and is set as the option + ``styler.sparse.index``. caption : str or tuple, optional Tuple (full_caption, short_caption), which results in ``\caption[short_caption]{{full_caption}}``; @@ -3354,15 +3360,15 @@ def to_latex( if self.ndim == 1: self = self.to_frame() if longtable is None: - longtable = config.get_option("display.latex.longtable") + longtable = config.get_option("styler.latex.environment") == "longtable" if escape is None: - escape = config.get_option("display.latex.escape") + escape = config.get_option("styler.format.escape") == "latex" if multicolumn is None: - multicolumn = config.get_option("display.latex.multicolumn") + multicolumn = config.get_option("styler.sparse.columns") if multicolumn_format is None: - multicolumn_format = config.get_option("display.latex.multicolumn_format") + multicolumn_format = config.get_option("styler.latex.multicol_align") if multirow is None: - multirow = config.get_option("display.latex.multirow") + multirow = config.get_option("styler.sparse.index") if column_format is not None and not isinstance(column_format, str): raise ValueError("`column_format` must be str or unicode") @@ -3448,7 +3454,9 @@ def _wrap(x, alt_format_): "label": label, "position": position, "column_format": column_format, - "clines": "skip-last;data" if multirow else None, + "clines": "skip-last;data" + if (multirow and isinstance(self.index, MultiIndex)) + else None, "bold_rows": bold_rows, } diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 42adf3f7b2826..066e04d91fc4b 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -799,7 +799,7 @@ def test_to_latex_escape_default(self, df_with_symbols): def test_to_latex_special_escape(self): df = DataFrame([r"a\b\c", r"^a^b^c", r"~a~b~c"]) - result = df.to_latex() + result = df.to_latex(escape=True) expected = _dedent( r""" \begin{tabular}{ll} @@ -818,7 +818,7 @@ def test_to_latex_special_escape(self): def test_to_latex_escape_special_chars(self): special_characters = ["&", "%", "$", "#", "_", "{", "}", "~", "^", "\\"] df = DataFrame(data=special_characters) - result = df.to_latex() + result = df.to_latex(escape=True) expected = _dedent( r""" \begin{tabular}{ll} @@ -1039,7 +1039,7 @@ def test_to_latex_multindex_header(self): # GH 16718 df = DataFrame({"a": [0], "b": [1], "c": [2], "d": [3]}) df = df.set_index(["a", "b"]) - observed = df.to_latex(header=["r1", "r2"]) + observed = df.to_latex(header=["r1", "r2"], multirow=False) expected = _dedent( r""" \begin{tabular}{llrr} @@ -1093,7 +1093,7 @@ def test_to_latex_multiindex_column_tabular(self): def test_to_latex_multiindex_small_tabular(self): df = DataFrame({("x", "y"): ["a"]}).T - result = df.to_latex() + result = df.to_latex(multirow=False) expected = _dedent( r""" \begin{tabular}{lll} @@ -1108,7 +1108,7 @@ def test_to_latex_multiindex_small_tabular(self): assert result == expected def test_to_latex_multiindex_tabular(self, multiindex_frame): - result = multiindex_frame.to_latex() + result = multiindex_frame.to_latex(multirow=False) expected = _dedent( r""" \begin{tabular}{llrrrr} @@ -1130,7 +1130,7 @@ def test_to_latex_multicolumn_tabular(self, multiindex_frame): # GH 14184 df = multiindex_frame.T df.columns.names = ["a", "b"] - result = df.to_latex() + result = df.to_latex(multirow=False) expected = _dedent( r""" \begin{tabular}{lrrrrr} @@ -1323,11 +1323,11 @@ def test_to_latex_multiindex_names(self, name0, name1, axes): else "" ) col_names = [n if (bool(n) and 1 in axes) else "" for n in names] - observed = df.to_latex() + observed = df.to_latex(multirow=False) # pylint: disable-next=consider-using-f-string expected = r"""\begin{tabular}{llrrrr} \toprule - & %s & \multicolumn{2}{l}{1} & \multicolumn{2}{l}{2} \\ + & %s & \multicolumn{2}{r}{1} & \multicolumn{2}{r}{2} \\ & %s & 3 & 4 & 3 & 4 \\ %s\midrule 1 & 3 & -1 & -1 & -1 & -1 \\ From 42aa203eca04c5b2786ab95fe0c305fbf701a36b Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Fri, 20 Jan 2023 19:18:47 +0100 Subject: [PATCH 3/9] fix up tests and document defaults --- doc/source/whatsnew/v2.0.0.rst | 7 +++++++ pandas/tests/frame/test_repr_info.py | 2 +- pandas/tests/io/formats/test_to_latex.py | 22 +++++++++++++--------- pandas/tests/series/test_repr.py | 2 +- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 983fdd397cf61..33aca5a42328e 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -481,6 +481,13 @@ The alternative options giving similar functionality are indicated below: ``styler.render.max_rows``, ``styler.render.max_columns`` and ``styler.render.max_elements``. +Note that due to this change some defaults have also changed: + +- ``multirow`` now defaults to *True*. +- ``multicol_align`` defaults to *"r"* instead of *"l"*. +- ``multicol_align`` defaults to *"r"* instead of *"l"*. +- ``escape`` now defaults to *False*. + Note that the behaviour of ``_repr_latex_`` is also changed. Previously setting ``display.latex.repr`` would generate LaTeX only when using nbconvert for a JupyterNotebook, and not when the user is running the notebook. Now the diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index 687bad07926d0..66d8084abea68 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -292,7 +292,7 @@ def test_latex_repr(self): \end{tabular} """ with option_context( - "display.latex.escape", False, "styler.render.repr", "latex" + "styler.format.escape", None, "styler.render.repr", "latex" ): df = DataFrame([[r"$\alpha$", "b", "c"], [1, 2, 3]]) result = df._repr_latex_() diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 066e04d91fc4b..940215a91a495 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -1135,7 +1135,7 @@ def test_to_latex_multicolumn_tabular(self, multiindex_frame): r""" \begin{tabular}{lrrrrr} \toprule - a & \multicolumn{2}{l}{c1} & \multicolumn{2}{l}{c2} & c3 \\ + a & \multicolumn{2}{r}{c1} & \multicolumn{2}{r}{c2} & c3 \\ b & 0 & 1 & 0 & 1 & 0 \\ \midrule 0 & 0 & 4 & 0 & 4 & 0 \\ @@ -1151,7 +1151,7 @@ def test_to_latex_multicolumn_tabular(self, multiindex_frame): def test_to_latex_index_has_name_tabular(self): # GH 10660 df = DataFrame({"a": [0, 0, 1, 1], "b": list("abab"), "c": [1, 2, 3, 4]}) - result = df.set_index(["a", "b"]).to_latex() + result = df.set_index(["a", "b"]).to_latex(multirow=False) expected = _dedent( r""" \begin{tabular}{llr} @@ -1172,12 +1172,16 @@ def test_to_latex_index_has_name_tabular(self): def test_to_latex_groupby_tabular(self): # GH 10660 df = DataFrame({"a": [0, 0, 1, 1], "b": list("abab"), "c": [1, 2, 3, 4]}) - result = df.groupby("a").describe().to_latex(float_format="{:.1f}".format) + result = ( + df.groupby("a") + .describe() + .to_latex(float_format="{:.1f}".format, escape=True) + ) expected = _dedent( r""" \begin{tabular}{lrrrrrrrr} \toprule - & \multicolumn{8}{l}{c} \\ + & \multicolumn{8}{r}{c} \\ & count & mean & std & min & 25\% & 50\% & 75\% & max \\ a & & & & & & & & \\ \midrule @@ -1200,7 +1204,7 @@ def test_to_latex_multiindex_dupe_level(self): df = DataFrame( index=pd.MultiIndex.from_tuples([("A", "c"), ("B", "c")]), columns=["col"] ) - result = df.to_latex() + result = df.to_latex(multirow=False) expected = _dedent( r""" \begin{tabular}{lll} @@ -1221,7 +1225,7 @@ def test_to_latex_multicolumn_default(self, multicolumn_frame): r""" \begin{tabular}{lrrrrr} \toprule - & \multicolumn{2}{l}{c1} & \multicolumn{2}{l}{c2} & c3 \\ + & \multicolumn{2}{r}{c1} & \multicolumn{2}{r}{c2} & c3 \\ & 0 & 1 & 0 & 1 & 0 \\ \midrule 0 & 0 & 5 & 0 & 5 & 0 \\ @@ -1236,7 +1240,7 @@ def test_to_latex_multicolumn_default(self, multicolumn_frame): assert result == expected def test_to_latex_multicolumn_false(self, multicolumn_frame): - result = multicolumn_frame.to_latex(multicolumn=False) + result = multicolumn_frame.to_latex(multicolumn=False, multicolumn_format="l") expected = _dedent( r""" \begin{tabular}{lrrrrr} @@ -1347,7 +1351,7 @@ def test_to_latex_multiindex_nans(self, one_row): df = DataFrame({"a": [None, 1], "b": [2, 3], "c": [4, 5]}) if one_row: df = df.iloc[[0]] - observed = df.set_index(["a", "b"]).to_latex() + observed = df.set_index(["a", "b"]).to_latex(multirow=False) expected = _dedent( r""" \begin{tabular}{llr} @@ -1369,7 +1373,7 @@ def test_to_latex_multiindex_nans(self, one_row): def test_to_latex_non_string_index(self): # GH 19981 df = DataFrame([[1, 2, 3]] * 2).set_index([0, 1]) - result = df.to_latex() + result = df.to_latex(multirow=False) expected = _dedent( r""" \begin{tabular}{llr} diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py index 43a6c7028883b..11ecac5115323 100644 --- a/pandas/tests/series/test_repr.py +++ b/pandas/tests/series/test_repr.py @@ -219,7 +219,7 @@ def test_latex_repr(self): \end{tabular} """ with option_context( - "display.latex.escape", False, "styler.render.repr", "latex" + "styler.format.escape", None, "styler.render.repr", "latex" ): s = Series([r"$\alpha$", "b", "c"]) assert result == s._repr_latex_() From 2b263206458e5fc87a5d9ccdd79bd44d71d6ce13 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Mon, 23 Jan 2023 19:29:23 +0100 Subject: [PATCH 4/9] CLN: remove redundant latex generation code --- pandas/tests/io/formats/test_to_latex.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 940215a91a495..8c66963bbb438 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -782,20 +782,10 @@ def test_to_latex_escape_false(self, df_with_symbols): assert result == expected def test_to_latex_escape_default(self, df_with_symbols): - result = df_with_symbols.to_latex() # default: escape=True - expected = _dedent( - r""" - \begin{tabular}{lll} - \toprule - & co\$e\textasciicircum x\$ & co\textasciicircum l1 \\ - \midrule - a & a & a \\ - b & b & b \\ - \bottomrule - \end{tabular} - """ - ) - assert result == expected + # gh50871: in v2.0 escape is False by default (styler.format.escape=None) + default = df_with_symbols.to_latex() + specified_true = df_with_symbols.to_latex(escape=True) + assert default != specified_true def test_to_latex_special_escape(self): df = DataFrame([r"a\b\c", r"^a^b^c", r"~a~b~c"]) From a91bc0d7f340fc294e35a36d2814d73e9512c4d1 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Mon, 23 Jan 2023 19:31:07 +0100 Subject: [PATCH 5/9] whats new text fix --- doc/source/whatsnew/v2.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 33aca5a42328e..52c64ed425eee 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -484,7 +484,7 @@ The alternative options giving similar functionality are indicated below: Note that due to this change some defaults have also changed: - ``multirow`` now defaults to *True*. -- ``multicol_align`` defaults to *"r"* instead of *"l"*. +- ``multirow_align`` defaults to *"r"* instead of *"l"*. - ``multicol_align`` defaults to *"r"* instead of *"l"*. - ``escape`` now defaults to *False*. From c11bac964714e59e51870e008a5c4c94fd4ddca4 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Wed, 25 Jan 2023 20:20:44 +0100 Subject: [PATCH 6/9] add versionchanged --- pandas/core/generic.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 2de93ee156663..3b527ba6dfde9 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3268,11 +3268,18 @@ def to_latex( By default, the value will be read from the pandas config module, and set to `True` if the option ``styler.latex.environment`` is `"longtable"`. + + .. versionchanged:: 2.0.0 + The pandas option affecting this argument has changed. escape : bool, optional By default, the value will be read from the pandas config module and set to `True` if the option ``styler.format.escape`` is `"latex"`. When set to False prevents from escaping latex special characters in column names. + + .. versionchanged:: 2.0.0 + The pandas option affecting this argument has changed, as has the + default value. encoding : str, optional A string representing the encoding to use in the output file, defaults to 'utf-8'. @@ -3282,10 +3289,17 @@ def to_latex( Use \multicolumn to enhance MultiIndex columns. The default will be read from the config module, and is set as the option ``styler.sparse.columns``. + + .. versionchanged:: 2.0.0 + The pandas option affecting this argument has changed. multicolumn_format : str, default 'l' The alignment for multicolumns, similar to `column_format` The default will be read from the config module, and is set as the option ``styler.latex.multicol_align``. + + .. versionchanged:: 2.0.0 + The pandas option affecting this argument has changed, as has the + default value. multirow : bool, default False Use \multirow to enhance MultiIndex rows. Requires adding a \usepackage{{multirow}} to your LaTeX preamble. Will print @@ -3293,6 +3307,10 @@ def to_latex( rows, separating groups via clines. The default will be read from the pandas config module, and is set as the option ``styler.sparse.index``. + + .. versionchanged:: 2.0.0 + The pandas option affecting this argument has changed, as has the + default value. caption : str or tuple, optional Tuple (full_caption, short_caption), which results in ``\caption[short_caption]{{full_caption}}``; From d1f20ac99100f7ff6099e1636aae52dac59869e2 Mon Sep 17 00:00:00 2001 From: JHM Darbyshire <24256554+attack68@users.noreply.github.com> Date: Tue, 31 Jan 2023 19:02:27 +0100 Subject: [PATCH 7/9] Update pandas/core/generic.py Co-authored-by: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 3b527ba6dfde9..f9756e9aed42d 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3300,7 +3300,7 @@ def to_latex( .. versionchanged:: 2.0.0 The pandas option affecting this argument has changed, as has the default value. - multirow : bool, default False + multirow : bool, default True Use \multirow to enhance MultiIndex rows. Requires adding a \usepackage{{multirow}} to your LaTeX preamble. Will print centered labels (instead of top-aligned) across the contained From 8c88ff703e5e17c3b60971173bc393f1fc4e4a7b Mon Sep 17 00:00:00 2001 From: JHM Darbyshire <24256554+attack68@users.noreply.github.com> Date: Tue, 31 Jan 2023 19:03:30 +0100 Subject: [PATCH 8/9] Update pandas/core/generic.py --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index f9756e9aed42d..dde2a05c5a57e 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3292,7 +3292,7 @@ def to_latex( .. versionchanged:: 2.0.0 The pandas option affecting this argument has changed. - multicolumn_format : str, default 'l' + multicolumn_format : str, default 'r' The alignment for multicolumns, similar to `column_format` The default will be read from the config module, and is set as the option ``styler.latex.multicol_align``. From 162ae167ca691f44ad5759714c8aa403dae1d170 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Thu, 2 Feb 2023 19:49:03 +0100 Subject: [PATCH 9/9] add to version changed --- pandas/core/generic.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index dde2a05c5a57e..162c59af94c23 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3279,7 +3279,7 @@ def to_latex( .. versionchanged:: 2.0.0 The pandas option affecting this argument has changed, as has the - default value. + default value to `False`. encoding : str, optional A string representing the encoding to use in the output file, defaults to 'utf-8'. @@ -3299,7 +3299,7 @@ def to_latex( .. versionchanged:: 2.0.0 The pandas option affecting this argument has changed, as has the - default value. + default value to "r". multirow : bool, default True Use \multirow to enhance MultiIndex rows. Requires adding a \usepackage{{multirow}} to your LaTeX preamble. Will print @@ -3310,7 +3310,7 @@ def to_latex( .. versionchanged:: 2.0.0 The pandas option affecting this argument has changed, as has the - default value. + default value to `True`. caption : str or tuple, optional Tuple (full_caption, short_caption), which results in ``\caption[short_caption]{{full_caption}}``;