Skip to content

ENH: added optional caption and label arguments to DataFrame.to_latex() #25437

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 27 commits into from
Sep 3, 2019
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8982b90
ENH: added optional caption and label support to DataFrame.to_latex()…
jeschwar Feb 25, 2019
2ce8c67
PEP8 compliance for ENH #25436
jeschwar Feb 25, 2019
0e9d6c7
added versionadded lines in NDFrame.to_latex() docstring (#25436)
jeschwar Mar 2, 2019
4e615d2
removed UserWarning when only caption is passed to NDFrame.to_latex()…
jeschwar Mar 2, 2019
911a491
moved code for table beginning and end writing into functions (#25436)
jeschwar Mar 4, 2019
1a19e3a
Merge remote-tracking branch 'upstream/master' into tolatex_caption_l…
jeschwar Mar 22, 2019
59e7f04
removed use of pytest fixture 'frame' which was not doing anything (#…
jeschwar Mar 22, 2019
3e9cf63
LatexFormatter methods for creating begin/end latex environments retu…
jeschwar Apr 12, 2019
5e31aa5
revised docstring for NDFrame.to_latex() (#25436)
jeschwar Apr 12, 2019
86b3d31
added whatsnew entry (#25436)
jeschwar Apr 27, 2019
3994a65
revised docstrings to follow numpydoc format (#25436)
jeschwar May 5, 2019
961aed3
merge master (#25436)
jeschwar Jun 27, 2019
3eb433b
reverted to methodology of commit 911a491 (#25436)
jeschwar Jun 27, 2019
a7df686
added Parameters to docstrings in pandas/io/formats/latex.py (#25436)
jeschwar Jul 19, 2019
4969d3b
changed location of LatexFormatter._write_tabular_end() in source cod…
jeschwar Jul 19, 2019
1f4ef45
negated logic used in if-statements in LatexFormatter._write_*() meth…
jeschwar Jul 19, 2019
b9640de
revised docstring for NDFrame.to_latex() (#25436)
jeschwar Jul 19, 2019
7bdc15f
merge master (#25436)
jeschwar Jul 29, 2019
4a1cd9d
removed entry from whatsnew/v0.25.0.rst (#25436)
jeschwar Jul 30, 2019
b6a52aa
revised version numbers in rst directives to 0.26.0 (#25436)
jeschwar Jul 30, 2019
3d45fe5
created whatsnew/v0.26.0.rst and added entry (#25436)
jeschwar Jul 30, 2019
bf34040
moved whatsnew entry from v0.26.0.rst to v1.0.0.rst (#25436)
jeschwar Aug 21, 2019
6c8bf33
ran black on latex.py and test_to_latex.py (#25436)
jeschwar Aug 21, 2019
6366cfa
merge master (#25436)
jeschwar Aug 29, 2019
6da6760
corrected version number in NDFrame.to_latex() docstring (#25436)
jeschwar Aug 31, 2019
b97b083
Merge remote-tracking branch 'upstream/master' into tolatex_caption_l…
TomAugspurger Sep 3, 2019
2c0f993
fix docstring
TomAugspurger Sep 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ including other versions of pandas.

Enhancements
~~~~~~~~~~~~

-
- :meth:`DataFrame.to_latex` now accepts ``caption`` and ``label`` arguments (:issue:`25436`)
-

.. _whatsnew_1000.enhancements.other:
Expand Down
29 changes: 25 additions & 4 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2924,15 +2924,21 @@ def to_latex(
multicolumn=None,
multicolumn_format=None,
multirow=None,
caption=None,
label=None,
):
r"""
Render an object to a LaTeX tabular environment table.
Render object to a LaTeX tabular, longtable, or nested table/tabular.

Render an object to a tabular environment table. You can splice
this into a LaTeX document. Requires \usepackage{booktabs}.
Requires ``\usepackage{booktabs}``. The output can be copy/pasted
into a main LaTeX document or read from an external file
with ``\input{table.tex}``.

.. versionchanged:: 0.20.2
Added to Series
Added to Series.

.. versionchanged:: 0.26.0
Added caption and label arguments.

Parameters
----------
Expand Down Expand Up @@ -3001,7 +3007,20 @@ def to_latex(
from the pandas config module.

.. versionadded:: 0.20.0

caption : str, optional
The LaTeX caption to be placed inside ``\caption{}`` in the output.

.. versionadded:: 1.0.0

label : str, optional
The LaTeX label to be placed inside ``\label{}`` in the output.
This is used with ``\ref{}`` in the main ``.tex`` file.

.. versionadded:: 1.0.0

%(returns)s

See Also
--------
DataFrame.to_string : Render a DataFrame to a console-friendly
Expand Down Expand Up @@ -3060,6 +3079,8 @@ def to_latex(
multicolumn=multicolumn,
multicolumn_format=multicolumn_format,
multirow=multirow,
caption=caption,
label=label,
)

def to_csv(
Expand Down
4 changes: 4 additions & 0 deletions pandas/io/formats/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,8 @@ def to_latex(
multicolumn: bool = False,
multicolumn_format: Optional[str] = None,
multirow: bool = False,
caption: Optional[str] = None,
label: Optional[str] = None,
) -> Optional[str]:
"""
Render a DataFrame to a LaTeX tabular/longtable environment output.
Expand All @@ -902,6 +904,8 @@ def to_latex(
multicolumn=multicolumn,
multicolumn_format=multicolumn_format,
multirow=multirow,
caption=caption,
label=label,
).get_result(buf=buf, encoding=encoding)

def _format_col(self, i: int) -> List[str]:
Expand Down
128 changes: 118 additions & 10 deletions pandas/io/formats/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def __init__(
multicolumn: bool = False,
multicolumn_format: Optional[str] = None,
multirow: bool = False,
caption: Optional[str] = None,
label: Optional[str] = None,
):
self.fmt = formatter
self.frame = self.fmt.frame
Expand All @@ -45,11 +47,14 @@ def __init__(
self.multicolumn = multicolumn
self.multicolumn_format = multicolumn_format
self.multirow = multirow
self.caption = caption
self.label = label
self.escape = self.fmt.escape

def write_result(self, buf: IO[str]) -> None:
"""
Render a DataFrame to a LaTeX tabular/longtable environment output.
Render a DataFrame to a LaTeX tabular, longtable, or table/tabular
environment output.
"""

# string representation of the columns
Expand Down Expand Up @@ -114,12 +119,12 @@ def pad_empties(x):
"not {typ}".format(typ=type(column_format))
)

if not self.longtable:
buf.write("\\begin{{tabular}}{{{fmt}}}\n".format(fmt=column_format))
buf.write("\\toprule\n")
if self.longtable:
self._write_longtable_begin(buf, column_format)
else:
buf.write("\\begin{{longtable}}{{{fmt}}}\n".format(fmt=column_format))
buf.write("\\toprule\n")
self._write_tabular_begin(buf, column_format)

buf.write("\\toprule\n")

ilevels = self.frame.index.nlevels
clevels = self.frame.columns.nlevels
Expand Down Expand Up @@ -183,11 +188,10 @@ def pad_empties(x):
if self.multirow and i < len(strrows) - 1:
self._print_cline(buf, i, len(strcols))

if not self.longtable:
buf.write("\\bottomrule\n")
buf.write("\\end{tabular}\n")
if self.longtable:
self._write_longtable_end(buf)
else:
buf.write("\\end{longtable}\n")
self._write_tabular_end(buf)

def _format_multicolumn(self, row: List[str], ilevels: int) -> List[str]:
r"""
Expand Down Expand Up @@ -268,3 +272,107 @@ def _print_cline(self, buf: IO[str], i: int, icol: int) -> None:
buf.write("\\cline{{{cl:d}-{icol:d}}}\n".format(cl=cl[1], icol=icol))
# remove entries that have been written to buffer
self.clinebuf = [x for x in self.clinebuf if x[0] != i]

def _write_tabular_begin(self, buf, column_format):
"""
Write the beginning of a tabular environment or
nested table/tabular environments including caption and label.

Parameters
----------
buf : string or file handle
File path or object. If not specified, the result is returned as
a string.
column_format : str, default None
The columns format as specified in `LaTeX table format
<https://en.wikibooks.org/wiki/LaTeX/Tables>`__ e.g 'rcl'
for 3 columns

"""
if self.caption is not None or self.label is not None:
# then write output in a nested table/tabular environment
if self.caption is None:
caption_ = ""
else:
caption_ = "\n\\caption{{{}}}".format(self.caption)

if self.label is None:
label_ = ""
else:
label_ = "\n\\label{{{}}}".format(self.label)

buf.write("\\begin{{table}}\n\\centering{}{}\n".format(caption_, label_))
else:
# then write output only in a tabular environment
pass

buf.write("\\begin{{tabular}}{{{fmt}}}\n".format(fmt=column_format))

def _write_tabular_end(self, buf):
"""
Write the end of a tabular environment or nested table/tabular
environment.

Parameters
----------
buf : string or file handle
File path or object. If not specified, the result is returned as
a string.

"""
buf.write("\\bottomrule\n")
buf.write("\\end{tabular}\n")
if self.caption is not None or self.label is not None:
buf.write("\\end{table}\n")
else:
pass

def _write_longtable_begin(self, buf, column_format):
"""
Write the beginning of a longtable environment including caption and
label if provided by user.

Parameters
----------
buf : string or file handle
File path or object. If not specified, the result is returned as
a string.
column_format : str, default None
The columns format as specified in `LaTeX table format
<https://en.wikibooks.org/wiki/LaTeX/Tables>`__ e.g 'rcl'
for 3 columns

"""
buf.write("\\begin{{longtable}}{{{fmt}}}\n".format(fmt=column_format))

if self.caption is not None or self.label is not None:
if self.caption is None:
pass
else:
buf.write("\\caption{{{}}}".format(self.caption))

if self.label is None:
pass
else:
buf.write("\\label{{{}}}".format(self.label))

# a double-backslash is required at the end of the line
# as discussed here:
# https://tex.stackexchange.com/questions/219138
buf.write("\\\\\n")
else:
pass

@staticmethod
def _write_longtable_end(buf):
"""
Write the end of a longtable environment.

Parameters
----------
buf : string or file handle
File path or object. If not specified, the result is returned as
a string.

"""
buf.write("\\end{longtable}\n")
Loading