From e9188b8adbcf30e63ae6b29e15b284851e549810 Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Fri, 7 Jul 2017 12:23:59 -0400 Subject: [PATCH 01/12] Fix css selectors for displaying DataFrames in notebook (part of HTMLFormatter) --- pandas/io/formats/format.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 0627ca9179509..c88ab59c33295 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1118,20 +1118,27 @@ def write_tr(self, line, indent=0, indent_delta=4, header=False, self.write('', indent) def write_style(self): - template = dedent("""\ - """) + template_first = """\ + """ + template_select = """\ + .dataframe %s { + %s: %s; + }""" + element_props = [('tbody tr th:only-of-type','vertical-align','middle'), + ('tbody tr th','vertical-align','top')] + if isinstance(self.columns, MultiIndex): + element_props.append(('thead th','text-align','left')) + if all((self.fmt.has_index_names, self.fmt.index, self.fmt.show_index_names)): + element_props.append(('thead th:last-of-type','text-align','right')) + else: + element_props.append(('thead th','text-align','right')) + template_mid = '\n\n'.join(map(lambda t: template_select%t, + element_props)) + template = dedent('\n'.join((template_first, + template_mid, + template_last))) if self.notebook: self.write(template) From 17194ae8cf6ba8a5d096ac0b66798aa52fc0be5d Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Fri, 7 Jul 2017 15:39:22 -0400 Subject: [PATCH 02/12] Fix css selectors for displaying DataFrames in notebook (part of HTMLFormatter) --- pandas/io/formats/format.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index c88ab59c33295..1a6ad48722ae1 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1129,9 +1129,9 @@ def write_style(self): element_props = [('tbody tr th:only-of-type','vertical-align','middle'), ('tbody tr th','vertical-align','top')] if isinstance(self.columns, MultiIndex): - element_props.append(('thead th','text-align','left')) + element_props.append(('thead tr th','text-align','left')) if all((self.fmt.has_index_names, self.fmt.index, self.fmt.show_index_names)): - element_props.append(('thead th:last-of-type','text-align','right')) + element_props.append(('thead tr:last-of-type th','text-align','right')) else: element_props.append(('thead th','text-align','right')) template_mid = '\n\n'.join(map(lambda t: template_select%t, From 907dbd54fd7d28dd4dce776c55eb790a305c5a0d Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Mon, 10 Jul 2017 15:07:04 -0700 Subject: [PATCH 03/12] BUG: Fix css for displaying DataFrames in notebook (#16792) --- pandas/io/formats/format.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 1a6ad48722ae1..e28c6b9370669 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1130,7 +1130,9 @@ def write_style(self): ('tbody tr th','vertical-align','top')] if isinstance(self.columns, MultiIndex): element_props.append(('thead tr th','text-align','left')) - if all((self.fmt.has_index_names, self.fmt.index, self.fmt.show_index_names)): + if all((self.fmt.has_index_names, + self.fmt.index, + self.fmt.show_index_names)): element_props.append(('thead tr:last-of-type th','text-align','right')) else: element_props.append(('thead th','text-align','right')) From 77ef9dae6da4344497e0d8b9146913bd8ec38ad4 Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Thu, 20 Jul 2017 11:27:02 -0400 Subject: [PATCH 04/12] BUG: Fix css for displaying DataFrames in notebook (#16792) --- pandas/tests/io/formats/test_to_html.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index 9f4e532ec2287..f80cbb31aa78a 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -1863,12 +1863,12 @@ def test_to_html_no_index_max_rows(self): def test_to_html_notebook_has_style(self): df = pd.DataFrame({"A": [1, 2, 3]}) result = df.to_html(notebook=True) - assert "thead tr:only-child" in result + assert "tbody tr th:only-of-type" in result def test_to_html_notebook_has_no_style(self): df = pd.DataFrame({"A": [1, 2, 3]}) result = df.to_html() - assert "thead tr:only-child" not in result + assert "tbody tr th:only-of-type" not in result def test_to_html_with_index_names_false(self): # gh-16493 From 35488a25a023c937d9be3f546885593b2ef56b44 Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Thu, 20 Jul 2017 11:34:08 -0400 Subject: [PATCH 05/12] PEP8 fixes --- pandas/io/formats/format.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index e28c6b9370669..b394cf6c56147 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1126,17 +1126,27 @@ def write_style(self): .dataframe %s { %s: %s; }""" - element_props = [('tbody tr th:only-of-type','vertical-align','middle'), - ('tbody tr th','vertical-align','top')] + element_props = [('tbody tr th:only-of-type', + 'vertical-align', + 'middle'), + ('tbody tr th', + 'vertical-align', + 'top')] if isinstance(self.columns, MultiIndex): - element_props.append(('thead tr th','text-align','left')) - if all((self.fmt.has_index_names, - self.fmt.index, + element_props.append(('thead tr th', + 'text-align', + 'left')) + if all((self.fmt.has_index_names, + self.fmt.index, self.fmt.show_index_names)): - element_props.append(('thead tr:last-of-type th','text-align','right')) + element_props.append(('thead tr:last-of-type th', + 'text-align', + 'right')) else: - element_props.append(('thead th','text-align','right')) - template_mid = '\n\n'.join(map(lambda t: template_select%t, + element_props.append(('thead th', + 'text-align', + 'right')) + template_mid = '\n\n'.join(map(lambda t: template_select % t, element_props)) template = dedent('\n'.join((template_first, template_mid, From 7fa67cbf026f0ab8f6c2cf0423844a410085c7c3 Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Thu, 20 Jul 2017 13:27:38 -0400 Subject: [PATCH 06/12] Added whatsnew entry --- doc/source/whatsnew/v0.21.0.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 8c71681582063..9283c24e0b85f 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -160,6 +160,7 @@ I/O ^^^ - Bug in :func:`read_csv` in which non integer values for the header argument generated an unhelpful / unrelated error message (:issue:`16338`) +- Bug in ``DataFrame.to_html()`` with ``notebook=True`` where DataFrames with named indexes or non-MultiIndex indexes had undesired horizontal or vertical alignment for column or row labels, respectively (:issue:`16792`) Plotting From e0325f261429ee33849c3a76b1ce7518a429156b Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Thu, 20 Jul 2017 13:32:16 -0400 Subject: [PATCH 07/12] indices --- doc/source/whatsnew/v0.21.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 9283c24e0b85f..c3331bc68b904 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -160,7 +160,7 @@ I/O ^^^ - Bug in :func:`read_csv` in which non integer values for the header argument generated an unhelpful / unrelated error message (:issue:`16338`) -- Bug in ``DataFrame.to_html()`` with ``notebook=True`` where DataFrames with named indexes or non-MultiIndex indexes had undesired horizontal or vertical alignment for column or row labels, respectively (:issue:`16792`) +- Bug in ``DataFrame.to_html()`` with ``notebook=True`` where DataFrames with named indices or non-MultiIndex indices had undesired horizontal or vertical alignment for column or row labels respectively (:issue:`16792`) Plotting From 0370dd4610d2dd7d2dee33b4a7e09b56036e7168 Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Tue, 12 Sep 2017 00:23:48 -0700 Subject: [PATCH 08/12] Added more assertions to test. --- pandas/tests/io/formats/test_to_html.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index f21c187cacf96..773a2bcdc083d 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -1869,11 +1869,17 @@ def test_to_html_notebook_has_style(self): df = pd.DataFrame({"A": [1, 2, 3]}) result = df.to_html(notebook=True) assert "tbody tr th:only-of-type" in result + assert "vertical-align: middle;" in result + assert "thead th" in result + assert "text-align: right;" in result def test_to_html_notebook_has_no_style(self): df = pd.DataFrame({"A": [1, 2, 3]}) result = df.to_html() assert "tbody tr th:only-of-type" not in result + assert "vertical-align: middle;" not in result + assert "thead th" not in result + assert "text-align: right;" not in result def test_to_html_with_index_names_false(self): # gh-16493 From 45204155c9e62f65222085df4c09e0c212f4bd93 Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Tue, 12 Sep 2017 01:00:25 -0700 Subject: [PATCH 09/12] Fixed error --- pandas/tests/io/formats/test_to_html.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index 773a2bcdc083d..194b5ba3e0276 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -1871,7 +1871,6 @@ def test_to_html_notebook_has_style(self): assert "tbody tr th:only-of-type" in result assert "vertical-align: middle;" in result assert "thead th" in result - assert "text-align: right;" in result def test_to_html_notebook_has_no_style(self): df = pd.DataFrame({"A": [1, 2, 3]}) @@ -1879,7 +1878,6 @@ def test_to_html_notebook_has_no_style(self): assert "tbody tr th:only-of-type" not in result assert "vertical-align: middle;" not in result assert "thead th" not in result - assert "text-align: right;" not in result def test_to_html_with_index_names_false(self): # gh-16493 From c44df8334a2873b28c2f08c9b66b36f9a755c8ad Mon Sep 17 00:00:00 2001 From: maxwasserman Date: Mon, 18 Sep 2017 08:39:00 -0700 Subject: [PATCH 10/12] Added comment explaining the use of the scoped attribute. --- pandas/io/formats/format.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index e85192acbfc2b..ea9317bc5aea3 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1132,6 +1132,9 @@ def write_tr(self, line, indent=0, indent_delta=4, header=False, self.write('', indent) def write_style(self): + # We use the "scoped" attribute here so that the desired + # style properties for the data frame are not then applied + # throughout the entire notebook template_first = """\