Pandas version checks
- [X] I have checked that the issue still exists on the latest versions of the docs on
main
here
Location of the documentation
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_html.html
Documentation problem
Based on the doc str
Whether the generated HTML is for IPython Notebook.
I was expecting the generated HTML when setting notebook=True
to look more similar in the browser to how the Styler
looks looks in Jupyter.
import pandas as pd
df = pd.util.testing.makeDataFrame()
df.style.format("{:.2}").background_gradient(cmap="viridis").to_html(
"notebook=False.html", notebook=False
)
df.style.format("{:.2}").background_gradient(cmap="viridis").to_html(
"notebook=True.html", notebook=True
)
What I actually get is notebook=True.html
and notebook=False.html
looking identical.
Jupyter (expected) | Browser actual (with notebook=True/False ) |
---|---|
Suggested fix for documentation
Would be great if the doc string could be more specific on what effect setting to notebook=True
is supposed to have.
Comment From: attack68
You are using Styler.to_html
since df.style
yields a Styler
object. You are not using DataFrame.to_html
.
Styler.to_html
has no argument notebook
and therefore it has no effect.
Comment From: janosh
Ah, my bad. Is it deliberately missing from Styler.to_html
? If not, could this issue be reopened and turned into a feature request?
Comment From: attack68
Yes it is deliberately missing from Styler because it is an old argument that used to provide minor data alignment for text in columns. If you compare the output from DataFrame.to_html with the only difference visible in the HTML is,
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
Styler
has a set_table_styles
and other methods available to completely customise the entire table CSS, not just include this very specific block of code (which I believe is now out of date with the behaviour of newer Jupyter and Colab notebooks anyway).
You seem to be suggesting that notebook=True
makes the HTML automatically look the same as the Jupyter notebook display. It doesn't. Jupyter has its own custom CSS for rendering tables within its cells. Different versions of Jupyter and Colab use different settings and will result in different looking tables. There is no point in creating a setting in pandas that attempts to copy the CSS styles of another software that can change their visual look in a new version. The objective is to give users the ability to define their own.
If you are interested in exploring some different CSS attrubute value pairs, here are those that JupyterNotebook attributes to tables, observed with Chrome element inspectior:
Comment From: janosh
You seem to be suggesting that
notebook=True
makes the HTML automatically look the same as the Jupyter notebook display.
Yes, that was my meaning.
It doesn't. Jupyter has its own custom CSS for rendering tables within its cells. Different versions of Jupyter and Colab use different settings and will result in different looking tables. There is no point in creating a setting in pandas that attempts to copy the CSS styles of another software that can change their visual look in a new version. The objective is to give users the ability to define their own.
I see, that's a fair point. Started using df.set_table_styles()
last night but thought it a bit clunky:
styles = {
"": [("font-family", "sans-serif"), ("border-collapse", "collapse")],
"td, th": [
("border", "1px solid #ddd"),
("text-align", "left"),
("padding", "8px"),
],
}
df_styled.set_table_styles([dict(selector=sel, props=styles[sel]) for sel in styles])
This seems like a more natural syntax:
styles = {
"": "font-family: sans-serif; border-collapse: collapse;",
"td, th": "border: 1px solid #ddd; text-align: left; padding: 8px;",
}
df_styled.set_table_styles(styles)
But probably no interest in supporting that?
Anyway, final point: Maybe the notebook
kwarg in df.to_html
should be deprecated?
Comment From: attack68
As documented you can actually do this.
styles = {"": "color: red;", "th": "font-weight: bold;}
s.set_table_styles([{"selector": k, props: v} for k, v in styles.items()])
The dict version is reserved for allowing users to specific column only styles which is also useful.
A lot of things in df.to_html
should be deprecated. It has been difficult to get concensus on changing the whole thing.
Comment From: janosh
Ah, I missed that CSS strings are supported. Should have tried that. Thanks for pointing it out.
The dict version is reserved for allowing users to specific column only styles which is also useful.
I see. There could be a flag as: Literal['columns', 'selectors']
:
styles = {
"": "font-family: sans-serif; border-collapse: collapse;",
"td, th": "border: 1px solid #ddd; text-align: left; padding: 8px;",
}
df_styled.set_table_styles(styles, as='selectors')
styles = {
"col_1": "background: black; color: white;",
"col_2": "font-weight: bold;",
}
df_styled.set_table_styles(styles, as='columns')
Comment From: attack68
There could be, and actually that might even be better. But I'm not sure its better to introduce a new format after 6 years, with many stackoverflow questions following the current format. Also Im not sure we would get round to changing this before 2.0, which is the only sensible version where this change could be introduced.
Comment From: janosh
Should I open a new issue to discuss adding as: Literal['columns', 'selectors']
in v2?