Skip to content

Commit 814dbe8

Browse files
danieljljreback
authored andcommitted
Fix undesired UX behavior of DataFrame output in IPython Notebook #10231
1 parent 48c7200 commit 814dbe8

File tree

4 files changed

+54
-25
lines changed

4 files changed

+54
-25
lines changed

doc/source/whatsnew/v0.16.2.txt

+5-10
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,12 @@ See the :ref:`documentation <basics.pipe>` for more. (:issue:`10129`)
8383

8484
.. _whatsnew_0162.enhancements.other:
8585

86-
Other enhancements
86+
Other Enhancements
8787
^^^^^^^^^^^^^^^^^^
8888

89-
.. _whatsnew_0162.api:
90-
91-
Backwards incompatible API changes
92-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
89+
- Removed the duplicate scroll bars in the ``DataFrame`` HTML representation when displaying in an ``IPython notebook`` v3.0 or greater. Note that the notebook has a ``toggle output scrolling`` feature to automate the display of very large frames. (:issue:`10231`)
9390

94-
.. _whatsnew_0162.api_breaking:
95-
96-
.. _whatsnew_0162.api_breaking.other:
91+
.. _whatsnew_0162.api:
9792

9893
Other API Changes
9994
^^^^^^^^^^^^^^^^^
@@ -108,7 +103,7 @@ Other API Changes
108103
Performance Improvements
109104
~~~~~~~~~~~~~~~~~~~~~~~~
110105

111-
- Improved ``Series.resample`` performance with dtype=datetime64[ns] (:issue:`7754`)
106+
- Improved ``Series.resample`` performance with ``dtype=datetime64[ns]`` (:issue:`7754`)
112107
- Increase performance of ``str.split`` when ``expand=True`` (:issue:`10081`)
113108

114109
.. _whatsnew_0162.bug_fixes:
@@ -173,4 +168,4 @@ Bug Fixes
173168

174169
- Bug where MySQL interface could not handle numeric table/column names (:issue:`10255`)
175170

176-
- Bug in ``read_csv`` with a ``date_parser`` that returned a ``datetime64`` array of other time resolution than ``[ns]`` (:issue:`10245`).
171+
- Bug in ``read_csv`` with a ``date_parser`` that returned a ``datetime64`` array of other time resolution than ``[ns]`` (:issue:`10245`)

pandas/core/format.py

+28-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import print_function
3+
from distutils.version import LooseVersion
34
# pylint: disable=W0141
45

56
import sys
@@ -692,13 +693,20 @@ def _format_col(self, i):
692693
space=self.col_space
693694
)
694695

695-
def to_html(self, classes=None):
696+
def to_html(self, classes=None, notebook=False):
696697
"""
697698
Render a DataFrame to a html table.
699+
700+
Parameters
701+
----------
702+
notebook : {True, False}, optional, default False
703+
Whether the generated HTML is for IPython Notebook.
704+
698705
"""
699706
html_renderer = HTMLFormatter(self, classes=classes,
700707
max_rows=self.max_rows,
701-
max_cols=self.max_cols)
708+
max_cols=self.max_cols,
709+
notebook=notebook)
702710
if hasattr(self.buf, 'write'):
703711
html_renderer.write_result(self.buf)
704712
elif isinstance(self.buf, compat.string_types):
@@ -808,7 +816,8 @@ class HTMLFormatter(TableFormatter):
808816

809817
indent_delta = 2
810818

811-
def __init__(self, formatter, classes=None, max_rows=None, max_cols=None):
819+
def __init__(self, formatter, classes=None, max_rows=None, max_cols=None,
820+
notebook=False):
812821
self.fmt = formatter
813822
self.classes = classes
814823

@@ -823,6 +832,7 @@ def __init__(self, formatter, classes=None, max_rows=None, max_cols=None):
823832
self.show_dimensions = self.fmt.show_dimensions
824833
self.is_truncated = (self.max_rows < len(self.fmt.frame) or
825834
self.max_cols < len(self.fmt.columns))
835+
self.notebook = notebook
826836

827837
def write(self, s, indent=0):
828838
rs = com.pprint_thing(s)
@@ -890,6 +900,17 @@ def write_result(self, buf):
890900
'not %s') % type(self.classes))
891901
_classes.extend(self.classes)
892902

903+
if self.notebook:
904+
div_style = ''
905+
try:
906+
import IPython
907+
if IPython.__version__ < LooseVersion('3.0.0'):
908+
div_style = ' style="max-width:1500px;overflow:auto;"'
909+
except ImportError:
910+
pass
911+
912+
self.write('<div{0}>'.format(div_style))
913+
893914
self.write('<table border="1" class="%s">' % ' '.join(_classes),
894915
indent)
895916

@@ -902,6 +923,10 @@ def write_result(self, buf):
902923
by = chr(215) if compat.PY3 else unichr(215) # ×
903924
self.write(u('<p>%d rows %s %d columns</p>') %
904925
(len(frame), by, len(frame.columns)))
926+
927+
if self.notebook:
928+
self.write('</div>')
929+
905930
_put_lines(buf, self.elements)
906931

907932
def _write_header(self, indent):

pandas/core/frame.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,9 @@ def _repr_html_(self):
538538
max_cols = get_option("display.max_columns")
539539
show_dimensions = get_option("display.show_dimensions")
540540

541-
return ('<div style="max-height:1000px;'
542-
'max-width:1500px;overflow:auto;">\n' +
543-
self.to_html(max_rows=max_rows, max_cols=max_cols,
544-
show_dimensions=show_dimensions) + '\n</div>')
541+
return self.to_html(max_rows=max_rows, max_cols=max_cols,
542+
show_dimensions=show_dimensions,
543+
notebook=True)
545544
else:
546545
return None
547546

@@ -1349,7 +1348,8 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
13491348
header=True, index=True, na_rep='NaN', formatters=None,
13501349
float_format=None, sparsify=None, index_names=True,
13511350
justify=None, bold_rows=True, classes=None, escape=True,
1352-
max_rows=None, max_cols=None, show_dimensions=False):
1351+
max_rows=None, max_cols=None, show_dimensions=False,
1352+
notebook=False):
13531353
"""
13541354
Render a DataFrame as an HTML table.
13551355
@@ -1388,7 +1388,7 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
13881388
max_rows=max_rows,
13891389
max_cols=max_cols,
13901390
show_dimensions=show_dimensions)
1391-
formatter.to_html(classes=classes)
1391+
formatter.to_html(classes=classes, notebook=notebook)
13921392

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

pandas/tests/test_format.py

+15-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import print_function
3+
from distutils.version import LooseVersion
34
import re
45

56
from pandas.compat import range, zip, lrange, StringIO, PY3, lzip, u
@@ -14,6 +15,14 @@
1415
from numpy.random import randn
1516
import numpy as np
1617

18+
div_style = ''
19+
try:
20+
import IPython
21+
if IPython.__version__ < LooseVersion('3.0.0'):
22+
div_style = ' style="max-width:1500px;overflow:auto;"'
23+
except ImportError:
24+
pass
25+
1726
from pandas import DataFrame, Series, Index, Timestamp, MultiIndex, date_range, NaT
1827

1928
import pandas.core.format as fmt
@@ -892,7 +901,7 @@ def test_to_html_truncate(self):
892901
fmt.set_option('display.max_columns',4)
893902
result = df._repr_html_()
894903
expected = '''\
895-
<div style="max-height:1000px;max-width:1500px;overflow:auto;">
904+
<div{0}>
896905
<table border="1" class="dataframe">
897906
<thead>
898907
<tr style="text-align: right;">
@@ -980,7 +989,7 @@ def test_to_html_truncate(self):
980989
</tbody>
981990
</table>
982991
<p>20 rows × 20 columns</p>
983-
</div>'''
992+
</div>'''.format(div_style)
984993
if sys.version_info[0] < 3:
985994
expected = expected.decode('utf-8')
986995
self.assertEqual(result, expected)
@@ -993,7 +1002,7 @@ def test_to_html_truncate_multi_index(self):
9931002
fmt.set_option('display.max_columns',7)
9941003
result = df._repr_html_()
9951004
expected = '''\
996-
<div style="max-height:1000px;max-width:1500px;overflow:auto;">
1005+
<div{0}>
9971006
<table border="1" class="dataframe">
9981007
<thead>
9991008
<tr>
@@ -1096,7 +1105,7 @@ def test_to_html_truncate_multi_index(self):
10961105
</tbody>
10971106
</table>
10981107
<p>8 rows × 8 columns</p>
1099-
</div>'''
1108+
</div>'''.format(div_style)
11001109
if sys.version_info[0] < 3:
11011110
expected = expected.decode('utf-8')
11021111
self.assertEqual(result, expected)
@@ -1110,7 +1119,7 @@ def test_to_html_truncate_multi_index_sparse_off(self):
11101119
fmt.set_option('display.multi_sparse',False)
11111120
result = df._repr_html_()
11121121
expected = '''\
1113-
<div style="max-height:1000px;max-width:1500px;overflow:auto;">
1122+
<div{0}>
11141123
<table border="1" class="dataframe">
11151124
<thead>
11161125
<tr>
@@ -1206,7 +1215,7 @@ def test_to_html_truncate_multi_index_sparse_off(self):
12061215
</tbody>
12071216
</table>
12081217
<p>8 rows × 8 columns</p>
1209-
</div>'''
1218+
</div>'''.format(div_style)
12101219
if sys.version_info[0] < 3:
12111220
expected = expected.decode('utf-8')
12121221
self.assertEqual(result, expected)

0 commit comments

Comments
 (0)