Skip to content

Commit aa67207

Browse files
toobazjreback
authored andcommitted
BUG: do not escape empty placeholder in to_latex() (#18670)
closes #18667
1 parent cc7a10c commit aa67207

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

doc/source/whatsnew/v0.22.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ I/O
307307
- Bug in :func:`read_msgpack` with a non existent file is passed in Python 2 (:issue:`15296`)
308308
- Bug in :func:`read_csv` where a ``MultiIndex`` with duplicate columns was not being mangled appropriately (:issue:`18062`)
309309
- Bug in :func:`read_sas` where a file with 0 variables gave an ``AttributeError`` incorrectly. Now it gives an ``EmptyDataError`` (:issue:`18184`)
310-
-
310+
- Bug in :func:`DataFrame.to_latex()` where pairs of braces meant to serve as invisible placeholders were escaped (:issue:`18667`)
311311
-
312312

313313
Plotting

pandas/io/formats/format.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ def get_col_type(dtype):
975975
.replace('#', '\\#').replace('{', '\\{')
976976
.replace('}', '\\}').replace('~', '\\textasciitilde')
977977
.replace('^', '\\textasciicircum').replace('&', '\\&')
978-
if x else '{}') for x in row]
978+
if (x and x != '{}') else '{}') for x in row]
979979
else:
980980
crow = [x if x else '{}' for x in row]
981981
if self.bold_rows and self.fmt.index:

pandas/tests/io/formats/test_to_latex.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,35 @@ def test_to_latex_no_bold_rows(self):
588588
\end{tabular}
589589
"""
590590
assert observed == expected
591+
592+
@pytest.mark.parametrize('name0', [None, 'named'])
593+
@pytest.mark.parametrize('name1', [None, 'named'])
594+
@pytest.mark.parametrize('axes', [[0], [1], [0, 1]])
595+
def test_to_latex_multiindex_names(self, name0, name1, axes):
596+
# GH 18667
597+
names = [name0, name1]
598+
mi = pd.MultiIndex.from_product([[1, 2], [3, 4]])
599+
df = pd.DataFrame(-1, index=mi.copy(), columns=mi.copy())
600+
for idx in axes:
601+
df.axes[idx].names = names
602+
603+
idx_names = tuple(n or '{}' for n in names)
604+
idx_names_row = ('%s & %s & & & & \\\\\n' % idx_names
605+
if (0 in axes and any(names)) else '')
606+
placeholder = '{}' if any(names) and 1 in axes else ' '
607+
col_names = [n if (bool(n) and 1 in axes) else placeholder
608+
for n in names]
609+
observed = df.to_latex()
610+
expected = r"""\begin{tabular}{llrrrr}
611+
\toprule
612+
& %s & \multicolumn{2}{l}{1} & \multicolumn{2}{l}{2} \\
613+
& %s & 3 & 4 & 3 & 4 \\
614+
%s\midrule
615+
1 & 3 & -1 & -1 & -1 & -1 \\
616+
& 4 & -1 & -1 & -1 & -1 \\
617+
2 & 3 & -1 & -1 & -1 & -1 \\
618+
& 4 & -1 & -1 & -1 & -1 \\
619+
\bottomrule
620+
\end{tabular}
621+
""" % tuple(list(col_names) + [idx_names_row])
622+
assert observed == expected

0 commit comments

Comments
 (0)