Skip to content
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

Custom column formatters for HTML in IPython, e.g. can show np 2D-array as image #9579

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 11 additions & 9 deletions pandas/core/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,8 @@ def _format_col(self, i):
return format_array(
frame.iloc[:, i]._values,
formatter, float_format=self.float_format, na_rep=self.na_rep,
space=self.col_space
space=self.col_space,
justify=getattr(formatter,'justify','right')
)

def to_html(self, classes=None, notebook=False):
Expand Down Expand Up @@ -820,7 +821,8 @@ def __init__(self, formatter, classes=None, max_rows=None, max_cols=None,
self.elements = []
self.bold_rows = self.fmt.kwds.get('bold_rows', False)
self.escape = self.fmt.kwds.get('escape', True)

if self.fmt.formatters is not None and len(self.fmt.formatters):
self.escape = tuple(getattr(f,'escape',self.escape) for f in self.fmt.formatters)
self.max_rows = max_rows or len(self.fmt.frame)
self.max_cols = max_cols or len(self.fmt.columns)
self.show_dimensions = self.fmt.show_dimensions
Expand All @@ -840,16 +842,16 @@ def write_th(self, s, indent=0, tags=None):

return self._write_cell(s, kind='th', indent=indent, tags=tags)

def write_td(self, s, indent=0, tags=None):
return self._write_cell(s, kind='td', indent=indent, tags=tags)
def write_td(self, s, indent=0, tags=None,column=None):
return self._write_cell(s, kind='td', indent=indent, tags=tags, column=column)

def _write_cell(self, s, kind='td', indent=0, tags=None):
def _write_cell(self, s, kind='td', indent=0, tags=None, column=None):
if tags is not None:
start_tag = '<%s %s>' % (kind, tags)
else:
start_tag = '<%s>' % kind

if self.escape:
if (self.escape if column is None or not isinstance(self.escape, tuple) else self.escape[column]):
# escape & first to prevent double escaping of &
esc = OrderedDict(
[('&', r'&amp;'), ('<', r'&lt;'), ('>', r'&gt;')]
Expand All @@ -861,7 +863,7 @@ def _write_cell(self, s, kind='td', indent=0, tags=None):
'%s%s</%s>' % (start_tag, rs, kind), indent)

def write_tr(self, line, indent=0, indent_delta=4, header=False,
align=None, tags=None, nindex_levels=0):
align=None, tags=None, nindex_levels=0, escape=None):
if tags is None:
tags = {}

Expand All @@ -876,7 +878,7 @@ def write_tr(self, line, indent=0, indent_delta=4, header=False,
if header or (self.bold_rows and i < nindex_levels):
self.write_th(s, indent, tags=val_tag)
else:
self.write_td(s, indent, tags=val_tag)
self.write_td(s, indent, tags=val_tag, column=i-nindex_levels)

indent -= indent_delta
self.write('</tr>', indent)
Expand Down
26 changes: 25 additions & 1 deletion pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1468,14 +1468,38 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
max_cols : int, optional
Maximum number of columns to show before truncating. If None, show
all.

formatters : callabable or dict/list/tuple of callables, optional
The keys to the dict are the column names, any missing or additional
names will be given defaults or ignored respectively. If list/tuple
the length should match the columns exactly.
Each callable can have an optional boolean `escape` attribute,
and an optional string `justify` attribute. See `_make_fixed_width`
Copy link
Member

Choose a reason for hiding this comment

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

Could you please give a brief description instead of referring to the source code? Also -- maybe add an example to the HTML a export docs? http://pandas-docs.github.io/pandas-docs-travis/io.html#io-html

function in `format.py` for meaning of `justify`. If `escape` is
not provided the primary `escape` argument is used (see above).
"""

if colSpace is not None: # pragma: no cover
warnings.warn("colSpace is deprecated, use col_space",
FutureWarning, stacklevel=2)
col_space = colSpace

# convert dict/single callable to list
if isinstance(formatters,dict):
formatters_list = []
for cname in self.columns:
if cname in formatters:
formatters_list.append(formatters[cname])
elif isinstance(cname,tuple):
# look through all the names in tuple and take the first
# matching name form the supplied formatters
formatters_list.append(next((formatters[n] for n in cname\
Copy link
Member

Choose a reason for hiding this comment

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

You don't need the backslash here inside parentheses.

if n in formatters),None))
else:
formatters_list.append(None)
formatters = tuple(formatters_list)
elif callable(formatters):
formatters = (formatters,)*len(self.columns)

formatter = fmt.DataFrameFormatter(self, buf=buf, columns=columns,
col_space=col_space, na_rep=na_rep,
formatters=formatters,
Expand Down