I\'m trying to replicate the output that jupyter uses for a pandas dataframe in their notebooks to html/css/js so that it\'s returnable by Flask jsonify
as html
I've made a few changes to your code to get the functionality you want:
thead
for the header and tbody
for the body. We can use this to specify the highlighting behavior as body-onlyIn Jupyter Notebook:
import pandas as pd
import numpy as np
from IPython.display import HTML
def hover(hover_color="#add8e6"):
return dict(selector="tbody tr:hover",
props=[("background-color", "%s" % hover_color)])
styles = [
#table properties
dict(selector=" ",
props=[("margin","0"),
("font-family",'"Helvetica", "Arial", sans-serif'),
("border-collapse", "collapse"),
("border","none"),
("border", "2px solid #ccf")
]),
#header color - optional
dict(selector="thead",
props=[("background-color","#cc8484")
]),
#background shading
dict(selector="tbody tr:nth-child(even)",
props=[("background-color", "#fff")]),
dict(selector="tbody tr:nth-child(odd)",
props=[("background-color", "#eee")]),
#cell spacing
dict(selector="td",
props=[("padding", ".5em")]),
#header cell properties
dict(selector="th",
props=[("font-size", "125%"),
("text-align", "center")]),
#caption placement
dict(selector="caption",
props=[("caption-side", "bottom")]),
#render hover last to override background-color
hover()
]
html = (df.style.set_table_styles(styles)
.set_caption("Hover to highlight."))
html
...but is it still beautiful when we output the HTML file?? Yes. You can do some more CSS styling to get it just right (font-size, font-family, text-decoration, margin/padding, etc) but this gives you a start. See below:
print(html.render())
<style type="text/css" >
#T_3e73cfd2_396c_11e8_9d70_240a645b34fc {
margin: 0;
font-family: "Helvetica", "Arial", sans-serif;
border-collapse: collapse;
border: none;
border: 2px solid #ccf;
} #T_3e73cfd2_396c_11e8_9d70_240a645b34fc thead {
background-color: #cc8484;
} #T_3e73cfd2_396c_11e8_9d70_240a645b34fc tbody tr:nth-child(even) {
background-color: #fff;
} #T_3e73cfd2_396c_11e8_9d70_240a645b34fc tbody tr:nth-child(odd) {
background-color: #eee;
} #T_3e73cfd2_396c_11e8_9d70_240a645b34fc td {
padding: .5em;
} #T_3e73cfd2_396c_11e8_9d70_240a645b34fc th {
font-size: 125%;
text-align: center;
} #T_3e73cfd2_396c_11e8_9d70_240a645b34fc caption {
caption-side: bottom;
} #T_3e73cfd2_396c_11e8_9d70_240a645b34fc tbody tr:hover {
background-color: #add8e6;
}</style>
<table id="T_3e73cfd2_396c_11e8_9d70_240a645b34fc" ><caption>Hover to highlight.</caption>
<thead> <tr>
<th class="blank" ></th>
<th class="blank level0" ></th>
<th class="col_heading level0 col0" >0</th>
</tr> <tr>
<th class="index_name level0" >first</th>
<th class="index_name level1" >second</th>
<th class="blank" ></th>
</tr></thead>
<tbody> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row0" class="row_heading level0 row0" rowspan=2>bar</th>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row0" class="row_heading level1 row0" >one</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow0_col0" class="data row0 col0" >-0.130634</td>
</tr> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row1" class="row_heading level1 row1" >two</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow1_col0" class="data row1 col0" >1.17685</td>
</tr> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row2" class="row_heading level0 row2" rowspan=2>baz</th>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row2" class="row_heading level1 row2" >one</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow2_col0" class="data row2 col0" >0.500367</td>
</tr> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row3" class="row_heading level1 row3" >two</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow3_col0" class="data row3 col0" >0.555932</td>
</tr> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row4" class="row_heading level0 row4" rowspan=2>foo</th>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row4" class="row_heading level1 row4" >one</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow4_col0" class="data row4 col0" >-0.744553</td>
</tr> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row5" class="row_heading level1 row5" >two</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow5_col0" class="data row5 col0" >-1.41269</td>
</tr> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel0_row6" class="row_heading level0 row6" rowspan=2>qux</th>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row6" class="row_heading level1 row6" >one</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow6_col0" class="data row6 col0" >0.726728</td>
</tr> <tr>
<th id="T_3e73cfd2_396c_11e8_9d70_240a645b34fclevel1_row7" class="row_heading level1 row7" >two</th>
<td id="T_3e73cfd2_396c_11e8_9d70_240a645b34fcrow7_col0" class="data row7 col0" >-0.683555</td>
</tr></tbody>
</table>
Definitely took me a while to look for where the template is, but here it is, link.
I believe this includes all the CSS for notebook cell outputs, so you just need the table related parts (table, thead, tbody, th, etc) and tweak them to your liking. You still need to turn it in python, but to illustrate it works, here's the raw HTML
<style type="text/css" >
table {
border: none;
border-collapse: collapse;
border-spacing: 0;
color: black;
font-size: 12px;
table-layout: fixed;
}
thead {
border-bottom: 1px solid black;
vertical-align: bottom;
}
tr, th, td {
text-align: right;
vertical-align: middle;
padding: 0.5em 0.5em;
line-height: normal;
white-space: normal;
max-width: none;
border: none;
}
th {
font-weight: bold;
}
tbody tr:nth-child(odd) {
background: #f5f5f5;
}
tbody tr:hover {
background: rgba(66, 165, 245, 0.2);
}
</style><table id="T_32dd1d4a_f245_11ea_977b_005056813a0d" ><thead> <tr> <th class="blank" ></th> <th class="blank level0" ></th> <th class="col_heading level0 col0" >0</th> </tr> <tr> <th class="index_name level0" >first</th> <th class="index_name level1" >second</th> <th class="blank" ></th> </tr></thead><tbody>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row0" class="row_heading level0 row0" rowspan=2>bar</th>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row0" class="row_heading level1 row0" >one</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow0_col0" class="data row0 col0" >-0.466253</td>
</tr>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row1" class="row_heading level1 row1" >two</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow1_col0" class="data row1 col0" >-0.579658</td>
</tr>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row2" class="row_heading level0 row2" rowspan=2>baz</th>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row2" class="row_heading level1 row2" >one</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow2_col0" class="data row2 col0" >1.868159</td>
</tr>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row3" class="row_heading level1 row3" >two</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow3_col0" class="data row3 col0" >0.392282</td>
</tr>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row4" class="row_heading level0 row4" rowspan=2>foo</th>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row4" class="row_heading level1 row4" >one</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow4_col0" class="data row4 col0" >-2.427858</td>
</tr>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row5" class="row_heading level1 row5" >two</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow5_col0" class="data row5 col0" >-0.813941</td>
</tr>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel0_row6" class="row_heading level0 row6" rowspan=2>qux</th>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row6" class="row_heading level1 row6" >one</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow6_col0" class="data row6 col0" >0.110564</td>
</tr>
<tr>
<th id="T_32dd1d4a_f245_11ea_977b_005056813a0dlevel1_row7" class="row_heading level1 row7" >two</th>
<td id="T_32dd1d4a_f245_11ea_977b_005056813a0drow7_col0" class="data row7 col0" >0.834701</td>
</tr>
</tbody></table>