Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
1 change: 1 addition & 0 deletions doc/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ Serialization / IO / Conversion
Series.to_dense
Series.to_string
Series.to_clipboard
Series.to_latex

Sparse
~~~~~~
Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.20.2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Enhancements
~~~~~~~~~~~~

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

.. _whatsnew_0202.performance:

Expand Down
88 changes: 0 additions & 88 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1663,94 +1663,6 @@ def to_html(self, buf=None, columns=None, col_space=None, header=True,
if buf is None:
return formatter.buf.getvalue()

@Substitution(header='Write out column names. If a list of string is given, \
it is assumed to be aliases for the column names.')
@Appender(fmt.common_docstring + fmt.return_docstring, indents=1)
def to_latex(self, buf=None, columns=None, col_space=None, header=True,
index=True, na_rep='NaN', formatters=None, float_format=None,
sparsify=None, index_names=True, bold_rows=True,
column_format=None, longtable=None, escape=None,
encoding=None, decimal='.', multicolumn=None,
multicolumn_format=None, multirow=None):
r"""
Render a DataFrame to a tabular environment table. You can splice
this into a LaTeX document. Requires \usepackage{booktabs}.

`to_latex`-specific options:

bold_rows : boolean, default True
Make the row labels bold in the output
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
longtable : boolean, default will be read from the pandas config module
Default: False.
Use a longtable environment instead of tabular. Requires adding
a \usepackage{longtable} to your LaTeX preamble.
escape : boolean, default will be read from the pandas config module
Default: True.
When set to False prevents from escaping latex special
characters in column names.
encoding : str, default None
A string representing the encoding to use in the output file,
defaults to 'ascii' on Python 2 and 'utf-8' on Python 3.
decimal : string, default '.'
Character recognized as decimal separator, e.g. ',' in Europe.

.. versionadded:: 0.18.0

multicolumn : boolean, default True
Use \multicolumn to enhance MultiIndex columns.
The default will be read from the config module.

.. versionadded:: 0.20.0

multicolumn_format : str, default 'l'
The alignment for multicolumns, similar to `column_format`
The default will be read from the config module.

.. versionadded:: 0.20.0

multirow : boolean, 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.

.. versionadded:: 0.20.0

"""
# Get defaults from the pandas config
if longtable is None:
longtable = get_option("display.latex.longtable")
if escape is None:
escape = get_option("display.latex.escape")
if multicolumn is None:
multicolumn = get_option("display.latex.multicolumn")
if multicolumn_format is None:
multicolumn_format = get_option("display.latex.multicolumn_format")
if multirow is None:
multirow = get_option("display.latex.multirow")

formatter = fmt.DataFrameFormatter(self, buf=buf, columns=columns,
col_space=col_space, na_rep=na_rep,
header=header, index=index,
formatters=formatters,
float_format=float_format,
bold_rows=bold_rows,
sparsify=sparsify,
index_names=index_names,
escape=escape, decimal=decimal)
formatter.to_latex(column_format=column_format, longtable=longtable,
encoding=encoding, multicolumn=multicolumn,
multicolumn_format=multicolumn_format,
multirow=multirow)

if buf is None:
return formatter.buf.getvalue()

def info(self, verbose=None, buf=None, max_cols=None, memory_usage=None,
null_counts=None):
"""
Expand Down
91 changes: 90 additions & 1 deletion pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import pandas.core.common as com
import pandas.core.missing as missing
from pandas.io.formats.printing import pprint_thing
from pandas.io.formats.format import format_percentiles
from pandas.io.formats.format import format_percentiles, DataFrameFormatter
from pandas.tseries.frequencies import to_offset
from pandas import compat
from pandas.compat.numpy import function as nv
Expand Down Expand Up @@ -1502,6 +1502,95 @@ def to_xarray(self):
coords=coords,
)

_shared_docs['to_latex'] = """
Render an object to a tabular environment table. You can splice
this into a LaTeX document. Requires \\usepackage{booktabs}.

`to_latex`-specific options:

bold_rows : boolean, default True
Make the row labels bold in the output
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
longtable : boolean, default will be read from the pandas config module
Default: False.
Use a longtable environment instead of tabular. Requires adding
a \\usepackage{longtable} to your LaTeX preamble.
escape : boolean, default will be read from the pandas config module
Default: True.
When set to False prevents from escaping latex special
characters in column names.
encoding : str, default None
A string representing the encoding to use in the output file,
defaults to 'ascii' on Python 2 and 'utf-8' on Python 3.
decimal : string, default '.'
Character recognized as decimal separator, e.g. ',' in Europe.

.. versionadded:: 0.18.0

multicolumn : boolean, default True
Use \multicolumn to enhance MultiIndex columns.
The default will be read from the config module.

.. versionadded:: 0.20.0

multicolumn_format : str, default 'l'
The alignment for multicolumns, similar to `column_format`
The default will be read from the config module.

.. versionadded:: 0.20.0

multirow : boolean, 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.

.. versionadded:: 0.20.0
"""

@Substitution(header='Write out column names. If a list of string is given, \
it is assumed to be aliases for the column names.')
@Appender(_shared_docs['to_latex'] % _shared_doc_kwargs)
def to_latex(self, buf=None, columns=None, col_space=None, header=True,
index=True, na_rep='NaN', formatters=None, float_format=None,
sparsify=None, index_names=True, bold_rows=True,
column_format=None, longtable=None, escape=None,
encoding=None, decimal='.', multicolumn=None,
multicolumn_format=None, multirow=None):
# Get defaults from the pandas config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you'll need to start this with

if self.ndim == 1:
    self = self.to_frame()

then the rest of it should be ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this suggestion--doing the check here rather than invoking to_frame() in the Series _repr_latex method makes a lot of sense.

if longtable is None:
longtable = config.get_option("display.latex.longtable")
if escape is None:
escape = config.get_option("display.latex.escape")
if multicolumn is None:
multicolumn = config.get_option("display.latex.multicolumn")
if multicolumn_format is None:
multicolumn_format = config.get_option(
"display.latex.multicolumn_format")
if multirow is None:
multirow = config.get_option("display.latex.multirow")

formatter = DataFrameFormatter(self, buf=buf, columns=columns,
col_space=col_space, na_rep=na_rep,
header=header, index=index,
formatters=formatters,
float_format=float_format,
bold_rows=bold_rows,
sparsify=sparsify,
index_names=index_names,
escape=escape, decimal=decimal)
formatter.to_latex(column_format=column_format, longtable=longtable,
encoding=encoding, multicolumn=multicolumn,
multicolumn_format=multicolumn_format,
multirow=multirow)

if buf is None:
return formatter.buf.getvalue()

# ----------------------------------------------------------------------
# Fancy Indexing

Expand Down
10 changes: 10 additions & 0 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,16 @@ def get_values(self):
""" same as values (but handles sparseness conversions); is a view """
return self._data.get_values()

def _repr_latex_(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you actually remove this and move the _repr_latex_ from pandas/core/frame.py and to NDFrame in pandas/core/generic.py?

"""
Returns a LaTeX representation for a particular Series.
Mainly for use with nbconvert (jupyter notebook conversion to pdf).
"""
if get_option('display.latex.repr'):
return self.to_frame().to_latex()
else:
return None

@property
def asobject(self):
"""
Expand Down
20 changes: 19 additions & 1 deletion pandas/tests/series/test_repr.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import numpy as np
import pandas as pd

from pandas import (Index, Series, DataFrame, date_range)
from pandas import (Index, Series, DataFrame, date_range, option_context)
from pandas.core.index import MultiIndex

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

ts2 = ts.iloc[np.random.randint(0, len(ts) - 1, 400)]
repr(ts2).splitlines()[-1]

def test_latex_repr(self):
result = r"""\begin{tabular}{ll}
\toprule
{} & 0 \\
\midrule
0 & $\alpha$ \\
1 & b \\
2 & c \\
\bottomrule
\end{tabular}
"""
with option_context('display.latex.escape', False,
'display.latex.repr', True):
s = Series([r'$\alpha$', 'b', 'c'])
assert result == s._repr_latex_()

assert s._repr_latex_() is None