Skip to content

Commit 660805b

Browse files
author
Rebecca Sweger
committed
ENH: Add to_latex() method to Series (pandas-dev#16180)
This changeset adds _repr_latex_ to the Series class and moves the to_latex() method from the DataFrame class to the NDFrame class.
1 parent d5a681b commit 660805b

File tree

6 files changed

+120
-90
lines changed

6 files changed

+120
-90
lines changed

doc/source/api.rst

+1
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ Serialization / IO / Conversion
724724
Series.to_dense
725725
Series.to_string
726726
Series.to_clipboard
727+
Series.to_latex
727728

728729
Sparse
729730
~~~~~~

doc/source/whatsnew/v0.20.2.txt

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Enhancements
2020
~~~~~~~~~~~~
2121

2222
- Unblocked access to additional compression types supported in pytables: 'blosc:blosclz, 'blosc:lz4', 'blosc:lz4hc', 'blosc:snappy', 'blosc:zlib', 'blosc:zstd' (:issue:`14478`)
23+
- ``Series`` provides a ``to_latex`` method (:issue:`16180`)
2324

2425
.. _whatsnew_0202.performance:
2526

pandas/core/frame.py

-88
Original file line numberDiff line numberDiff line change
@@ -1663,94 +1663,6 @@ def to_html(self, buf=None, columns=None, col_space=None, header=True,
16631663
if buf is None:
16641664
return formatter.buf.getvalue()
16651665

1666-
@Substitution(header='Write out column names. If a list of string is given, \
1667-
it is assumed to be aliases for the column names.')
1668-
@Appender(fmt.common_docstring + fmt.return_docstring, indents=1)
1669-
def to_latex(self, buf=None, columns=None, col_space=None, header=True,
1670-
index=True, na_rep='NaN', formatters=None, float_format=None,
1671-
sparsify=None, index_names=True, bold_rows=True,
1672-
column_format=None, longtable=None, escape=None,
1673-
encoding=None, decimal='.', multicolumn=None,
1674-
multicolumn_format=None, multirow=None):
1675-
r"""
1676-
Render a DataFrame to a tabular environment table. You can splice
1677-
this into a LaTeX document. Requires \usepackage{booktabs}.
1678-
1679-
`to_latex`-specific options:
1680-
1681-
bold_rows : boolean, default True
1682-
Make the row labels bold in the output
1683-
column_format : str, default None
1684-
The columns format as specified in `LaTeX table format
1685-
<https://en.wikibooks.org/wiki/LaTeX/Tables>`__ e.g 'rcl' for 3
1686-
columns
1687-
longtable : boolean, default will be read from the pandas config module
1688-
Default: False.
1689-
Use a longtable environment instead of tabular. Requires adding
1690-
a \usepackage{longtable} to your LaTeX preamble.
1691-
escape : boolean, default will be read from the pandas config module
1692-
Default: True.
1693-
When set to False prevents from escaping latex special
1694-
characters in column names.
1695-
encoding : str, default None
1696-
A string representing the encoding to use in the output file,
1697-
defaults to 'ascii' on Python 2 and 'utf-8' on Python 3.
1698-
decimal : string, default '.'
1699-
Character recognized as decimal separator, e.g. ',' in Europe.
1700-
1701-
.. versionadded:: 0.18.0
1702-
1703-
multicolumn : boolean, default True
1704-
Use \multicolumn to enhance MultiIndex columns.
1705-
The default will be read from the config module.
1706-
1707-
.. versionadded:: 0.20.0
1708-
1709-
multicolumn_format : str, default 'l'
1710-
The alignment for multicolumns, similar to `column_format`
1711-
The default will be read from the config module.
1712-
1713-
.. versionadded:: 0.20.0
1714-
1715-
multirow : boolean, default False
1716-
Use \multirow to enhance MultiIndex rows.
1717-
Requires adding a \usepackage{multirow} to your LaTeX preamble.
1718-
Will print centered labels (instead of top-aligned)
1719-
across the contained rows, separating groups via clines.
1720-
The default will be read from the pandas config module.
1721-
1722-
.. versionadded:: 0.20.0
1723-
1724-
"""
1725-
# Get defaults from the pandas config
1726-
if longtable is None:
1727-
longtable = get_option("display.latex.longtable")
1728-
if escape is None:
1729-
escape = get_option("display.latex.escape")
1730-
if multicolumn is None:
1731-
multicolumn = get_option("display.latex.multicolumn")
1732-
if multicolumn_format is None:
1733-
multicolumn_format = get_option("display.latex.multicolumn_format")
1734-
if multirow is None:
1735-
multirow = get_option("display.latex.multirow")
1736-
1737-
formatter = fmt.DataFrameFormatter(self, buf=buf, columns=columns,
1738-
col_space=col_space, na_rep=na_rep,
1739-
header=header, index=index,
1740-
formatters=formatters,
1741-
float_format=float_format,
1742-
bold_rows=bold_rows,
1743-
sparsify=sparsify,
1744-
index_names=index_names,
1745-
escape=escape, decimal=decimal)
1746-
formatter.to_latex(column_format=column_format, longtable=longtable,
1747-
encoding=encoding, multicolumn=multicolumn,
1748-
multicolumn_format=multicolumn_format,
1749-
multirow=multirow)
1750-
1751-
if buf is None:
1752-
return formatter.buf.getvalue()
1753-
17541666
def info(self, verbose=None, buf=None, max_cols=None, memory_usage=None,
17551667
null_counts=None):
17561668
"""

pandas/core/generic.py

+89-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
import pandas.core.common as com
4646
import pandas.core.missing as missing
4747
from pandas.io.formats.printing import pprint_thing
48-
from pandas.io.formats.format import format_percentiles
48+
from pandas.io.formats.format import format_percentiles, DataFrameFormatter
4949
from pandas.tseries.frequencies import to_offset
5050
from pandas import compat
5151
from pandas.compat.numpy import function as nv
@@ -1502,6 +1502,94 @@ def to_xarray(self):
15021502
coords=coords,
15031503
)
15041504

1505+
_shared_docs['to_latex'] = """
1506+
Render an object to a tabular environment table. You can splice
1507+
this into a LaTeX document. Requires \\usepackage{booktabs}.
1508+
1509+
`to_latex`-specific options:
1510+
1511+
bold_rows : boolean, default True
1512+
Make the row labels bold in the output
1513+
column_format : str, default None
1514+
The columns format as specified in `LaTeX table format
1515+
<https://en.wikibooks.org/wiki/LaTeX/Tables>`__ e.g 'rcl' for 3
1516+
columns
1517+
longtable : boolean, default will be read from the pandas config module
1518+
Default: False.
1519+
Use a longtable environment instead of tabular. Requires adding
1520+
a \\usepackage{longtable} to your LaTeX preamble.
1521+
escape : boolean, default will be read from the pandas config module
1522+
Default: True.
1523+
When set to False prevents from escaping latex special
1524+
characters in column names.
1525+
encoding : str, default None
1526+
A string representing the encoding to use in the output file,
1527+
defaults to 'ascii' on Python 2 and 'utf-8' on Python 3.
1528+
decimal : string, default '.'
1529+
Character recognized as decimal separator, e.g. ',' in Europe.
1530+
1531+
.. versionadded:: 0.18.0
1532+
1533+
multicolumn : boolean, default True
1534+
Use \multicolumn to enhance MultiIndex columns.
1535+
The default will be read from the config module.
1536+
1537+
.. versionadded:: 0.20.0
1538+
1539+
multicolumn_format : str, default 'l'
1540+
The alignment for multicolumns, similar to `column_format`
1541+
The default will be read from the config module.
1542+
1543+
.. versionadded:: 0.20.0
1544+
1545+
multirow : boolean, default False
1546+
Use \multirow to enhance MultiIndex rows.
1547+
Requires adding a \\usepackage{multirow} to your LaTeX preamble.
1548+
Will print centered labels (instead of top-aligned)
1549+
across the contained rows, separating groups via clines.
1550+
The default will be read from the pandas config module.
1551+
1552+
.. versionadded:: 0.20.0
1553+
"""
1554+
1555+
@Substitution(header='Write out column names. If a list of string is given, \
1556+
it is assumed to be aliases for the column names.')
1557+
@Appender(_shared_docs['to_latex'] % _shared_doc_kwargs)
1558+
def to_latex(self, buf=None, columns=None, col_space=None, header=True,
1559+
index=True, na_rep='NaN', formatters=None, float_format=None,
1560+
sparsify=None, index_names=True, bold_rows=True,
1561+
column_format=None, longtable=None, escape=None,
1562+
encoding=None, decimal='.', multicolumn=None,
1563+
multicolumn_format=None, multirow=None):
1564+
# Get defaults from the pandas config
1565+
if longtable is None:
1566+
longtable = config.get_option("display.latex.longtable")
1567+
if escape is None:
1568+
escape = config.get_option("display.latex.escape")
1569+
if multicolumn is None:
1570+
multicolumn = config.get_option("display.latex.multicolumn")
1571+
if multicolumn_format is None:
1572+
multicolumn_format = config.get_option("display.latex.multicolumn_format")
1573+
if multirow is None:
1574+
multirow = config.get_option("display.latex.multirow")
1575+
1576+
formatter = DataFrameFormatter(self, buf=buf, columns=columns,
1577+
col_space=col_space, na_rep=na_rep,
1578+
header=header, index=index,
1579+
formatters=formatters,
1580+
float_format=float_format,
1581+
bold_rows=bold_rows,
1582+
sparsify=sparsify,
1583+
index_names=index_names,
1584+
escape=escape, decimal=decimal)
1585+
formatter.to_latex(column_format=column_format, longtable=longtable,
1586+
encoding=encoding, multicolumn=multicolumn,
1587+
multicolumn_format=multicolumn_format,
1588+
multirow=multirow)
1589+
1590+
if buf is None:
1591+
return formatter.buf.getvalue()
1592+
15051593
# ----------------------------------------------------------------------
15061594
# Fancy Indexing
15071595

pandas/core/series.py

+10
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,16 @@ def get_values(self):
391391
""" same as values (but handles sparseness conversions); is a view """
392392
return self._data.get_values()
393393

394+
def _repr_latex_(self):
395+
"""
396+
Returns a LaTeX representation for a particular Series.
397+
Mainly for use with nbconvert (jupyter notebook conversion to pdf).
398+
"""
399+
if get_option('display.latex.repr'):
400+
return self.to_frame().to_latex()
401+
else:
402+
return None
403+
394404
@property
395405
def asobject(self):
396406
"""

pandas/tests/series/test_repr.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import numpy as np
99
import pandas as pd
1010

11-
from pandas import (Index, Series, DataFrame, date_range)
11+
from pandas import (Index, Series, DataFrame, date_range, option_context)
1212
from pandas.core.index import MultiIndex
1313

1414
from pandas.compat import lrange, range, u
@@ -180,3 +180,21 @@ def test_timeseries_repr_object_dtype(self):
180180

181181
ts2 = ts.iloc[np.random.randint(0, len(ts) - 1, 400)]
182182
repr(ts2).splitlines()[-1]
183+
184+
def test_latex_repr(self):
185+
result = r"""\begin{tabular}{ll}
186+
\toprule
187+
{} & 0 \\
188+
\midrule
189+
0 & $\alpha$ \\
190+
1 & b \\
191+
2 & c \\
192+
\bottomrule
193+
\end{tabular}
194+
"""
195+
with option_context('display.latex.escape', False,
196+
'display.latex.repr', True):
197+
s = Series([r'$\alpha$', 'b', 'c'])
198+
assert result == s._repr_latex_()
199+
200+
assert s._repr_latex_() is None

0 commit comments

Comments
 (0)