Search code examples
pythonpython-2.7python-3.xpandassklearn-pandas

python3 + Pandas styles + Change alternate row color


Hi i am using Pandas and displaying a table. I there a function to apply alternate row color to make it clear to read. Using below code I am sending table in mail and it works.

my code:

count = 1000
df = pandas.DataFrame.from_dict(result)
df["Total"] = df.T.sum()

html = """<!DOCTYPE html>
<html>
    <body>
    <h3> %i</h3>
    {table_content}
    </body>
</html>
""" % count


# Create message container - the correct MIME type is
# multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = " Report"
msg['From'] = sender
msg['To'] = recipients


part2 = MIMEText(html.df(
    table_content=df.to_html(na_rep="0")), 'html')

msg.attach(part2)

Solution

  • You can use CSS, namely the tr:nth-child in combination with df.to_html(classes)

    Adopt to your case:

    from IPython.display import display, HTML
    from sklearn.datasets import load_iris
    import pandas as pd
    import numpy as np
    
    iris = load_iris()
    df = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                         columns= iris['feature_names'] + ['target'])
    HTML('''
            <style>
                .df tbody tr:nth-child(even) { background-color: lightblue; }
            </style>
            ''' + df.to_html(classes="df"))
    

    Screenshot from Jupyter notebook

    Update: Expanding to a specific example

    I slightly rearranged the code to allow adding css, as it was conflicting with {} used by .format. You can add your variables to html_variables dict and use %()s to embed them into html. If your html becomes too complicated I recommend looking at using some template engine to make it more robust. Otherwise the code below should be self-explanatory.

    html_template = '''<!DOCTYPE html>
    <html>
        <head>
        <style>.df tbody tr:nth-child(even) {background-color: lightblue;}</style>
        </head>
        <body>
        <h3>%(other_var)s</h3>
        %(table_content)s
        </body>
    </html>
    '''
    
    html_vars = {'other_var':'IRIS Dataset','table_content':df.to_html(classes="df")}
    
    html = html_template % html_vars
    
    # Create message container - the correct MIME type is
    # multipart/alternative.
    msg = MIMEMultipart('alternative')
    msg['Subject'] = "Report"
    msg['From'] = sender
    msg['To'] = recipient
    
    part2 = MIMEText(html, 'html')
    msg.attach(part2)