Update:
The issue seems to be with displaying the HTML with styling rendered by pandas in Google Chrome and Microsoft Edge.
JupyterLab in Firefox correctly displays all of the styled rows and correctly renders an output HTML file.
The updated questions are
- Why doesn't the HTML rendered by pandas completely display all the styling in Chrome or Edge?
- Is there a more efficient way to apply the styling done by pandas so the HTML also works in Chrome and Edge?
Versions:
pandas v1.2.4
Chrome v90.0.4430.93 (Official Build) (64-bit)
Edge v90.0.818.56 (Official build) (64-bit)
Original:
- Questions - they are interrelated:
- Why aren't all of the rows displaying the background styling in Jupyter or writing to HTML?
- All rows should have green styling, but the last 5 do not display the styling.
- How can all of the rows be made to display the background styling?
- Why aren't all of the rows displaying the background styling in Jupyter or writing to HTML?
- Given a large dataframe, in this case
474 rows x 35 columns
, the applied styling stops displaying. - If the number of rows or columns increases beyond this size, then more rows aren't displayed.
- We can see from the styling map, that the rows are correctly mapped with a background color, but it isn't displayed.
- If the number of rows or columns is reduced, then all of the rows display the correct styling.
- Tested in
jupyterlab v3.0.11
- Tested in
PyCharm 2021.1 (Professional Edition) Build #PY-211.6693.115, built on April 6, 2021
saving the redendered styler to a file has the same result, so this isn't just an issue withjupyter
. - Tested in the console
- This issue is reproducible on two different systems, that I have tried.
- If the shape is reduced to
471 rows × 35 columns
or474 rows × 34 columns
, then all rows correctly display the highlighting. - Associated pandas bug report: 40913
Reproducible DataFrame
import pandas as pd
import numpy as np
from faker import Faker # conda install -c conda-forge faker or pip install Faker
# for fake names
fake = Faker()
# test data
np.random.seed(365)
rows = 11000
# change 36 or 158 to test where the rows stop appearing
vals = {f'val{i}': np.random.randint(1, 11, size=(rows)) for i in range(1, 36)}
data = {'name': np.random.choice([fake.unique.name() for i in range(158)], size=rows),
'cat': np.random.randint(1, 4, size=(rows))}
data.update(vals)
df = pd.DataFrame(data)
# used to create the mask for the background color
mean = df.groupby('cat').mean().round(2)
# calculate the mean for each name and cat
cat_mean = df.groupby(['name', 'cat']).mean()
def color(x):
"""Function to apply background color"""
c1 = 'background-color: green'
c = ''
# compare columns
mask1 = x.gt(mean)
# DataFrame with same index and columns names as original filled empty strings
df1 = pd.DataFrame(c, index=x.index, columns=x.columns)
# modify values of df1 column by boolean mask
df1[mask1] = c1
display(df1)
return df1
# Last line in notebook displays the styled dataframe
cat_mean.style.apply(color, axis=None)
# Last line in PyCharm saving rendered styler to file - comment out when in Jupyter
cm = cat_mean.style.apply(color, axis=None).set_precision(3).render()
# save the output to an html file
with open('cm_test.html', 'w') as f:
f.write(cm)
Reference
- This answer was referenced for the function to apply the background color.
- This question is similar, but has no answer.
Output of pd.show_versions()
- All packages that were
None
, aren't shown to conserve space
INSTALLED VERSIONS
------------------
commit : f2c8480af2f25efdbd803218b9d87980f416563e
python : 3.8.8.final.0 or 3.9.2.final.0
python-bits : 64
OS : Windows
OS-release : 10
Version : 10.0.19041
machine : AMD64
processor : Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
byteorder : little
LOCALE : English_United States.1252
pandas : 1.2.3 or 1.2.4
numpy : 1.19.2
pytz : 2021.1
dateutil : 2.8.1
pip : 21.0.1
setuptools : 52.0.0.post20210125
Cython : 0.29.22
pytest : 6.2.3
sphinx : 3.5.3
xlsxwriter : 1.3.8
lxml.etree : 4.6.3
html5lib : 1.1
jinja2 : 2.11.3
IPython : 7.22.0
pandas_datareader: 0.9.0
bs4 : 4.9.3
bottleneck : 1.3.2
fsspec : 0.9.0
matplotlib : 3.3.4
numexpr : 2.7.3
openpyxl : 3.0.7
scipy : 1.6.2
sqlalchemy : 1.4.5
tables : 3.6.1
tabulate : 0.8.9
xlrd : 2.0.1
xlwt : 1.3.0
numba : 0.53.1
Workaround
Split DataFrame
- It's dissatisfying, but splitting the DataFrame and applying the style will work, since if reduces the overall size.
cat_mean.iloc[:237, :].style.apply(color, axis=None)
cat_mean.iloc[237:, :].style.apply(color, axis=None)
Save to Excel
- All rows are displayed correctly with the highlight color when saving to Excel
test = cat_mean.style.apply(color, axis=None)
test.to_excel('test.xlsx', engine='openpyxl')