Reputation: 630
I want to place a header
value below the title of the data frame data
below and get the Expected output, How would I be able to do that?
import pandas as pd
class SubclassedDataFrame(pd.DataFrame):
# normal properties
_metadata = ['description']
@property
def _constructor(self):
return SubclassedDataFrame
data = {"a": [1, 2, 3], "b": [10, 12, 13], "c": [230, 1, 3],"d": [8, 12, 9],}
df = SubclassedDataFrame(data)
title = 'Outputs'
header = 'header'
df = df.style.set_caption(title).set_table_styles([{
'selector': 'caption',
'props': [
('color', 'red'),
('font-size', '15px'),
('font-style', 'italic'),
('font-weight', 'bold'),
('text-align', 'center')
]
}])
display(df)
Output:
Expected output:
header
Upvotes: 4
Views: 5208
Reputation: 35676
There are 2 approaches:
One approach is to create a MultiIndex with header being the top level:
title = 'Outputs'
header = 'header'
# Add MultiIndex Header
df.columns = pd.MultiIndex.from_product([[header], df.columns])
styler = df.style.set_caption(title).set_table_styles([{
'selector': 'caption',
'props': [
('color', 'red'),
('font-size', '15px'),
('font-style', 'italic'),
('font-weight', 'bold'),
('text-align', 'center')
]
}])
display(styler)
This approach keeps the integrity of the pandas Styler object, and makes "header" a part of the table
object, being the first row in thead
.
The second approach is to create a Subclass of the Styler object and modify the jinja
templates.
templates/myhtml.tpl
:
{% extends "html_table.tpl" %}
{% block table %}
<div class="wrap">
{% if table_title %}
<h1 class="table-title">{{ table_title}}</h1>
{% endif %}
{% if table_header %}
<h2 class="table-header">{{ table_header }}</h2>
{% endif %}
{{ super() }}
</div>
{% endblock table %}
templates/mystyles.tpl
:
{% extends "html_style.tpl" %}
{% block style %}
{{ super() }}
<style>
.wrap {
display: inline-block;
}
.table-title {
color: red;
font-size: 15px !important;
font-style: italic;
font-weight: bold;
text-align: center;
margin: 0 2px !important;
}
.table-header {
text-align: center;
font-size: 13px !important;
margin: 0 2px !important;
}
</style>
{% endblock style %}
title = 'Outputs'
header = 'header'
# Build Styler Subclass from templates
MyStyler = Styler.from_custom_template(
"templates", # Folder to Search
html_table="myhtml.tpl", # HTML Template
html_style='mystyles.tpl' # CSS Template
)
# Get Styler For `df`
styler = MyStyler(df)
# Render with arguments and display
HTML(styler.render(table_title=title, table_header=header))
This approach moves some of the control away from the Styler object to the templates, but allows significantly more flexibility as it can be used to create additional HTML elements which is currently not supported by the Styler object.
Environment jupyter-notebook
Setup:
import pandas as pd
from IPython.display import HTML, display
from pandas.io.formats.style import Styler
class SubclassedDataFrame(pd.DataFrame):
# normal properties
_metadata = ['description']
@property
def _constructor(self):
return SubclassedDataFrame
data = {
"a": [1, 2, 3],
"b": [10, 12, 13],
"c": [230, 1, 3],
"d": [8, 12, 9]
}
df = SubclassedDataFrame(data)
Upvotes: 5