Skip to content

Commit 47a8e71

Browse files
TomAugspurgerjorisvandenbossche
authored andcommitted
ENH: add parameter for HTML border (#14061)
1 parent b6d3a81 commit 47a8e71

File tree

6 files changed

+57
-7
lines changed

6 files changed

+57
-7
lines changed

doc/source/options.rst

+3
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ display.width 80 Width of the display in characters.
392392
IPython qtconsole, or IDLE do not run in a
393393
terminal and hence it is not possible
394394
to correctly detect the width.
395+
html.border 1 A ``border=value`` attribute is
396+
inserted in the ``<table>`` tag
397+
for the DataFrame HTML repr.
395398
io.excel.xls.writer xlwt The default Excel writer engine for
396399
'xls' files.
397400
io.excel.xlsm.writer openpyxl The default Excel writer engine for

doc/source/whatsnew/v0.19.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ Other enhancements
427427
df.sort_values(by='row2', axis=1)
428428

429429
- Added documentation to :ref:`I/O<io.dtypes>` regarding the perils of reading in columns with mixed dtypes and how to handle it (:issue:`13746`)
430+
- :meth:`~DataFrame.to_html` now has a ``border`` argument to control the value in the opening ``<table>`` tag. The default is the value of the ``html.border`` option, which defaults to 1. This also affects the notebook HTML repr, but since Jupyter's CSS includes a border-width attribute, the visual effect is the same. (:issue:`11563`).
430431
- Raise ``ImportError`` in the sql functions when ``sqlalchemy`` is not installed and a connection string is used (:issue:`11920`).
431432
- Compatibility with matplotlib 2.0. Older versions of pandas should also work with matplotlib 2.0 (:issue:`13333`)
432433

pandas/core/config_init.py

+11
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,17 @@ def mpl_style_cb(key):
346346
cf.deprecate_option('display.height', msg=pc_height_deprecation_warning,
347347
rkey='display.max_rows')
348348

349+
pc_html_border_doc = """
350+
: int
351+
A ``border=value`` attribute is inserted in the ``<table>`` tag
352+
for the DataFrame HTML repr.
353+
"""
354+
355+
with cf.config_prefix('html'):
356+
cf.register_option('border', 1, pc_html_border_doc,
357+
validator=is_int)
358+
359+
349360
tc_sim_interactive_doc = """
350361
: boolean
351362
Whether to simulate interactive mode for purposes of testing

pandas/core/frame.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1560,7 +1560,8 @@ def to_html(self, buf=None, columns=None, col_space=None, header=True,
15601560
index=True, na_rep='NaN', formatters=None, float_format=None,
15611561
sparsify=None, index_names=True, justify=None, bold_rows=True,
15621562
classes=None, escape=True, max_rows=None, max_cols=None,
1563-
show_dimensions=False, notebook=False, decimal='.'):
1563+
show_dimensions=False, notebook=False, decimal='.',
1564+
border=None):
15641565
"""
15651566
Render a DataFrame as an HTML table.
15661567
@@ -1582,6 +1583,11 @@ def to_html(self, buf=None, columns=None, col_space=None, header=True,
15821583
Character recognized as decimal separator, e.g. ',' in Europe
15831584
15841585
.. versionadded:: 0.18.0
1586+
border : int
1587+
A ``border=border`` attribute is included in the opening
1588+
`<table>` tag. Default ``pd.options.html.border``.
1589+
1590+
.. versionadded:: 0.19.0
15851591
"""
15861592

15871593
formatter = fmt.DataFrameFormatter(self, buf=buf, columns=columns,
@@ -1597,7 +1603,7 @@ def to_html(self, buf=None, columns=None, col_space=None, header=True,
15971603
show_dimensions=show_dimensions,
15981604
decimal=decimal)
15991605
# TODO: a generic formatter wld b in DataFrameFormatter
1600-
formatter.to_html(classes=classes, notebook=notebook)
1606+
formatter.to_html(classes=classes, notebook=notebook, border=border)
16011607

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

pandas/formats/format.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -671,20 +671,28 @@ def _format_col(self, i):
671671
float_format=self.float_format, na_rep=self.na_rep,
672672
space=self.col_space, decimal=self.decimal)
673673

674-
def to_html(self, classes=None, notebook=False):
674+
def to_html(self, classes=None, notebook=False, border=None):
675675
"""
676676
Render a DataFrame to a html table.
677677
678678
Parameters
679679
----------
680+
classes : str or list-like
681+
classes to include in the `class` attribute of the opening
682+
``<table>`` tag, in addition to the default "dataframe".
680683
notebook : {True, False}, optional, default False
681684
Whether the generated HTML is for IPython Notebook.
685+
border : int
686+
A ``border=border`` attribute is included in the opening
687+
``<table>`` tag. Default ``pd.options.html.border``.
682688
683-
"""
689+
.. versionadded:: 0.19.0
690+
"""
684691
html_renderer = HTMLFormatter(self, classes=classes,
685692
max_rows=self.max_rows,
686693
max_cols=self.max_cols,
687-
notebook=notebook)
694+
notebook=notebook,
695+
border=border)
688696
if hasattr(self.buf, 'write'):
689697
html_renderer.write_result(self.buf)
690698
elif isinstance(self.buf, compat.string_types):
@@ -910,7 +918,7 @@ class HTMLFormatter(TableFormatter):
910918
indent_delta = 2
911919

912920
def __init__(self, formatter, classes=None, max_rows=None, max_cols=None,
913-
notebook=False):
921+
notebook=False, border=None):
914922
self.fmt = formatter
915923
self.classes = classes
916924

@@ -926,6 +934,9 @@ def __init__(self, formatter, classes=None, max_rows=None, max_cols=None,
926934
self.is_truncated = (self.max_rows < len(self.fmt.frame) or
927935
self.max_cols < len(self.fmt.columns))
928936
self.notebook = notebook
937+
if border is None:
938+
border = get_option('html.border')
939+
self.border = border
929940

930941
def write(self, s, indent=0):
931942
rs = pprint_thing(s)
@@ -1001,7 +1012,8 @@ def write_result(self, buf):
10011012

10021013
self.write('<div{0}>'.format(div_style))
10031014

1004-
self.write('<table border="1" class="%s">' % ' '.join(_classes),
1015+
self.write('<table border="%s" class="%s">' % (self.border,
1016+
' '.join(_classes)),
10051017
indent)
10061018

10071019
indent += self.indent_delta

pandas/tests/formats/test_format.py

+17
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,23 @@ def test_to_html_truncate_multi_index_sparse_off(self):
16501650
expected = expected.decode('utf-8')
16511651
self.assertEqual(result, expected)
16521652

1653+
def test_to_html_border(self):
1654+
df = DataFrame({'A': [1, 2]})
1655+
result = df.to_html()
1656+
assert 'border="1"' in result
1657+
1658+
def test_to_html_border_option(self):
1659+
df = DataFrame({'A': [1, 2]})
1660+
with pd.option_context('html.border', 0):
1661+
result = df.to_html()
1662+
self.assertTrue('border="0"' in result)
1663+
self.assertTrue('border="0"' in df._repr_html_())
1664+
1665+
def test_to_html_border_zero(self):
1666+
df = DataFrame({'A': [1, 2]})
1667+
result = df.to_html(border=0)
1668+
self.assertTrue('border="0"' in result)
1669+
16531670
def test_nonunicode_nonascii_alignment(self):
16541671
df = DataFrame([["aa\xc3\xa4\xc3\xa4", 1], ["bbbb", 2]])
16551672
rep_str = df.to_string()

0 commit comments

Comments
 (0)