Skip to content

BUG: (row) Index Name with to_html(header=False) is not displayed #24547

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

Merged
merged 2 commits into from
Jan 2, 2019
Merged
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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.24.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,7 @@ Notice how we now instead output ``np.nan`` itself instead of a stringified form
- Bug in :func:`to_html()` with ``index=False`` misses truncation indicators (...) on truncated DataFrame (:issue:`15019`, :issue:`22783`)
- Bug in :func:`to_html()` with ``index=False`` when both columns and row index are ``MultiIndex`` (:issue:`22579`)
- Bug in :func:`to_html()` with ``index_names=False`` displaying index name (:issue:`22747`)
- Bug in :func:`to_html()` with ``header=False`` not displaying row index names (:issue:`23788`)
- Bug in :func:`DataFrame.to_string()` that broke column alignment when ``index=False`` and width of first column's values is greater than the width of first column's header (:issue:`16839`, :issue:`13032`)
- Bug in :func:`DataFrame.to_string()` that caused representations of :class:`DataFrame` to not take up the whole window (:issue:`22984`)
- Bug in :func:`DataFrame.to_csv` where a single level MultiIndex incorrectly wrote a tuple. Now just the value of the index is written (:issue:`19589`).
Expand Down
46 changes: 27 additions & 19 deletions pandas/io/formats/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ def __init__(self, formatter, classes=None, notebook=False, border=None,
self.table_id = table_id
self.render_links = render_links

@property
def show_row_idx_names(self):
return all((self.fmt.has_index_names,
self.fmt.index,
self.fmt.show_index_names))

@property
def show_col_idx_names(self):
# see gh-22579
Expand Down Expand Up @@ -165,9 +171,7 @@ def write_style(self):
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 self.show_row_idx_names:
element_props.append(('thead tr:last-of-type th',
'text-align',
'right'))
Expand Down Expand Up @@ -228,17 +232,8 @@ def write_result(self, buf):

buffer_put_lines(buf, self.elements)

def _write_header(self, indent):
def _write_col_header(self, indent):
truncate_h = self.fmt.truncate_h

if not self.fmt.header:
# write nothing
return indent

self.write('<thead>', indent)

indent += self.indent_delta

if isinstance(self.columns, ABCMultiIndex):
template = 'colspan="{span:d}" halign="left"'

Expand Down Expand Up @@ -357,12 +352,25 @@ def _write_header(self, indent):
self.write_tr(row, indent, self.indent_delta, header=True,
align=align)

if all((self.fmt.has_index_names,
self.fmt.index,
self.fmt.show_index_names)):
row = ([x if x is not None else '' for x in self.frame.index.names]
+ [''] * (self.ncols + (1 if truncate_h else 0)))
self.write_tr(row, indent, self.indent_delta, header=True)
def _write_row_header(self, indent):
truncate_h = self.fmt.truncate_h
row = ([x if x is not None else '' for x in self.frame.index.names]
+ [''] * (self.ncols + (1 if truncate_h else 0)))
self.write_tr(row, indent, self.indent_delta, header=True)

def _write_header(self, indent):
if not (self.fmt.header or self.show_row_idx_names):
# write nothing
return indent

self.write('<thead>', indent)
indent += self.indent_delta

if self.fmt.header:
self._write_col_header(indent)

if self.show_row_idx_names:
self._write_row_header(indent)

indent -= self.indent_delta
self.write('</thead>', indent)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<table border="1" class="dataframe">
<thead>
<tr>
<th>index.name.0</th>
<th>index.name.1</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th rowspan="2" valign="top">a</th>
<th>b</th>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th>c</th>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<table border="1" class="dataframe">
<thead>
<tr>
<th>index.name</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th>1</th>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<table border="1" class="dataframe">
<tbody>
<tr>
<th rowspan="2" valign="top">a</th>
<th>b</th>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th>c</th>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<table border="1" class="dataframe">
<tbody>
<tr>
<th>0</th>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th>1</th>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<table border="1" class="dataframe">
<thead>
<tr>
<th>foo</th>
<th></th>
<th>baz</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th rowspan="2" valign="top">a</th>
<th rowspan="2" valign="top">c</th>
<th>e</th>
<td>0</td>
<td>1</td>
<td>...</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<th>f</th>
<td>8</td>
<td>9</td>
<td>...</td>
<td>14</td>
<td>15</td>
</tr>
<tr>
<th>...</th>
<th>...</th>
<th>...</th>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<th rowspan="2" valign="top">b</th>
<th rowspan="2" valign="top">d</th>
<th>e</th>
<td>48</td>
<td>49</td>
<td>...</td>
<td>54</td>
<td>55</td>
</tr>
<tr>
<th>f</th>
<td>56</td>
<td>57</td>
<td>...</td>
<td>62</td>
<td>63</td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<table border="1" class="dataframe">
<thead>
<tr>
<th>index.name</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>0</td>
<td>1</td>
<td>...</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<th>1</th>
<td>8</td>
<td>9</td>
<td>...</td>
<td>14</td>
<td>15</td>
</tr>
<tr>
<th>...</th>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<th>6</th>
<td>48</td>
<td>49</td>
<td>...</td>
<td>54</td>
<td>55</td>
</tr>
<tr>
<th>7</th>
<td>56</td>
<td>57</td>
<td>...</td>
<td>62</td>
<td>63</td>
</tr>
</tbody>
</table>
22 changes: 15 additions & 7 deletions pandas/tests/io/formats/test_to_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ def test_to_html_multi_indexes_index_false(self, datapath):
assert result == expected

@pytest.mark.parametrize('index_names', [True, False])
@pytest.mark.parametrize('header', [True, False])
@pytest.mark.parametrize('index', [True, False])
@pytest.mark.parametrize('column_index, column_type', [
(Index([0, 1]), 'unnamed_standard'),
Expand All @@ -448,25 +449,29 @@ def test_to_html_multi_indexes_index_false(self, datapath):
])
def test_to_html_basic_alignment(
self, datapath, row_index, row_type, column_index, column_type,
index, index_names):
index, header, index_names):
# GH 22747, GH 22579
df = DataFrame(np.zeros((2, 2), dtype=int),
index=row_index, columns=column_index)
result = df.to_html(index=index, index_names=index_names)
result = df.to_html(
index=index, header=header, index_names=index_names)

if not index:
row_type = 'none'
elif not index_names and row_type.startswith('named'):
row_type = 'un' + row_type

if not index_names and column_type.startswith('named'):
if not header:
column_type = 'none'
elif not index_names and column_type.startswith('named'):
column_type = 'un' + column_type

filename = 'index_' + row_type + '_columns_' + column_type
expected = expected_html(datapath, filename)
assert result == expected

@pytest.mark.parametrize('index_names', [True, False])
@pytest.mark.parametrize('header', [True, False])
@pytest.mark.parametrize('index', [True, False])
@pytest.mark.parametrize('column_index, column_type', [
(Index(np.arange(8)), 'unnamed_standard'),
Expand All @@ -488,19 +493,22 @@ def test_to_html_basic_alignment(
])
def test_to_html_alignment_with_truncation(
self, datapath, row_index, row_type, column_index, column_type,
index, index_names):
index, header, index_names):
# GH 22747, GH 22579
df = DataFrame(np.arange(64).reshape(8, 8),
index=row_index, columns=column_index)
result = df.to_html(max_rows=4, max_cols=4,
index=index, index_names=index_names)
result = df.to_html(
max_rows=4, max_cols=4,
index=index, header=header, index_names=index_names)

if not index:
row_type = 'none'
elif not index_names and row_type.startswith('named'):
row_type = 'un' + row_type

if not index_names and column_type.startswith('named'):
if not header:
column_type = 'none'
elif not index_names and column_type.startswith('named'):
column_type = 'un' + column_type

filename = 'trunc_df_index_' + row_type + '_columns_' + column_type
Expand Down