Pandas to_html Table Styling Techniques Using CSS and Styler

In this tutorial, you’ll learn how to apply various styling options to HTML tables generated from Pandas to_html using CSS or style DataFrames using DataFrame styler.

From adjusting text alignment and colors to conditional formatting to hide rows and columns and more.

 

 

Text Wrapping

Let’s explore how to implement text wrapping in a Pandas DataFrame.

import pandas as pd
data = {
    'Customer ID': [1001, 1002, 1003, 1004],
    'Feedback': [
        "Excellent service, but the billing process is confusing and lengthy.",
        "Overall good experience, though network coverage in rural areas needs improvement.",
        "Satisfied with the customer support, but the pricing could be more competitive.",
        "The internet speed is great, but experiencing frequent disconnections."
    ]
}
df = pd.DataFrame(data)
html_table = df.to_html(classes='table-style', escape=False)

# HTML style for text wrapping
html_style = """
<!DOCTYPE html>
<html>
<head>
<style>
    .table-style {
        border-collapse: collapse;
        width: 100%;
    }
    .table-style td, .table-style th {
        border: 1px solid #ddd;
        padding: 8px;
    }
    .table-style td {
        max-width: 150px;
        word-wrap: break-word;
    }
</style>
</head>
<body>
"""
complete_html = html_style + html_table + "</body></html>"
with open("styled_table.html", "w") as file:
    file.write(complete_html)

 

Text Alignment and Formatting

In this section, we’ll focus on customizing the text alignment and formatting within a table’s cells.

import pandas as pd
data = {
    'Customer ID': [1001, 1002, 1003, 1004],
    'Rating': [4, 3, 5, 2],
    'Comment': [
        "Great service!",
        "Satisfactory experience.",
        "Outstanding support!",
        "Needs improvement."
    ]
}
df = pd.DataFrame(data)

# Apply formatting directly through the styler
styled_df = df.style.set_properties(**{
    'text-align': 'center',
    'font-weight': 'bold',
    'font-style': 'italic'
}).set_table_styles([{
    'selector': 'td:nth-child(2)',
    'props': [('text-align', 'right')]
}, {
    'selector': 'td:nth-child(3)',
    'props': [('text-decoration', 'underline')]
}])
html_styled = styled_df.to_html(escape=False)
with open("formatted_table.html", "w") as file:
    file.write(html_styled)

The ‘Rating’ column is right-aligned, emphasizing the numeric nature of the data.

The ‘Comment’ column is underlined, drawing attention to customer feedback. All text is centered, bold, and italic, making the table more engaging.

 

Font & Color Customization

In this part, we will explore how to change font types, sizes, and colors within the table cells.

import pandas as pd
data = {
    'Interaction ID': [101, 102, 103, 104],
    'Summary': [
        "Inquiry about billing cycle",
        "Reported network issues",
        "Feedback on customer service",
        "Query about new plans"
    ],
    'Status': ['Resolved', 'Pending', 'Resolved', 'Pending']
}
df = pd.DataFrame(data)
styled_df = df.style.set_properties(**{
    'font-size': '15px',
    'color': 'darkblue'
}).set_table_styles([{
    'selector': 'th',
    'props': [('font-size', '18px'), ('font-family', 'Arial'), ('color', 'darkred')]
}, {
    'selector': 'td:nth-child(3)',
    'props': [('font-family', 'Helvetica'), ('font-style', 'italic')]
}])
html_styled = styled_df.to_html(escape=False)
with open("font_customized_table.html", "w") as file:
    file.write(html_styled)

The header row uses a larger font size, Arial typeface, and dark red color, making it stand out.

The ‘Status’ column is in italic Helvetica, subtly differentiating it from other information.

 

Conditional Formatting

In this section, we’ll apply conditional formatting to the HTML table.

import pandas as pd
data = {
    'Customer ID': [1001, 1002, 1003, 1004],
    'Satisfaction Score': [78, 85, 90, 65],
    'Response Time (hrs)': [2, 6, 1, 4]
}
df = pd.DataFrame(data)

# Define a function for conditional coloring
def color_score(val):
    color = 'red' if val < 70 else ('green' if val >= 85 else 'orange')
    return f'color: {color};'

# Apply conditional formatting
styled_df = df.style.applymap(color_score, subset=['Satisfaction Score'])

# Highlighting the maximum and minimum in 'Response Time (hrs)'
styled_df = styled_df.highlight_max(subset='Response Time (hrs)', color='lightgreen')
styled_df = styled_df.highlight_min(subset='Response Time (hrs)', color='lightcoral')
html_styled = styled_df.to_html(escape=False)
with open("conditional_formatted_table.html", "w") as file:
    file.write(html_styled)

The ‘Satisfaction Score’ cells are colored based on their value: red for scores below 70, orange for scores between 70 and 84, and green for scores 85 and above.

Additionally, the maximum and minimum values in the ‘Response Time (hrs)’ column are highlighted in light green and light coral, respectively.

 

Styling Columns and Rows

In this section, we’ll demonstrate how to style column headers, index labels, and specific rows in a DataFrame.

import pandas as pd
data = {
    'Service Type': ['Internet', 'Mobile', 'Cable TV', 'Landline'],
    'Average Rating': [4.2, 3.8, 4.5, 3.5],
    'Monthly Revenue ($)': [20000, 15000, 12000, 8000]
}
df = pd.DataFrame(data)
styled_df = df.style.set_table_styles([
    {'selector': 'th',
     'props': [('background-color', 'lightblue'), ('color', 'black'), ('font-weight', 'bold')]},
    {'selector': 'td',
     'props': [('text-align', 'center')]},
    {'selector': 'tr:nth-child(even)',
     'props': [('background-color', 'lightgray')]},
    {'selector': 'tr:nth-child(odd)',
     'props': [('background-color', 'white')]},
    {'selector': '.index_name',
     'props': [('color', 'darkblue'), ('font-style', 'italic')]}
], overwrite=False)

# Assigning a name to the index for styling purposes
styled_df.index.name = 'Service ID'
html_styled = styled_df.to_html(escape=False)
with open("styled_columns_rows_table.html", "w") as file:
    file.write(html_styled)

The HTML table includes custom styles for column headers, which are highlighted in light blue with bold text, and centered text in each cell for uniformity.

 

Set Column Width

Let’s see how to specify column widths through CSS styling.

import pandas as pd
data = {
    'Plan Name': ['Unlimited Data', 'Family Pack', 'Budget Plan', 'Business Plan'],
    'Monthly Cost ($)': [50, 80, 30, 100],
    'Data Limit (GB)': [None, 100, 10, 200]
}
df = pd.DataFrame(data)
html_table = df.to_html(classes='table-style', escape=False)
css_set_column_width = """
<style>
    .table-style {
        width: 100%; /* Adjust the table width as needed */
    }
    .table-style th, .table-style td {
        width: 33%; /* Divide the width equally among columns, or set specific widths */
    }
    /* Example: Set specific width for each column */
    .table-style th:nth-child(1), .table-style td:nth-child(1) { width: 40%; }
    .table-style th:nth-child(2), .table-style td:nth-child(2) { width: 30%; }
    .table-style th:nth-child(3), .table-style td:nth-child(3) { width: 30%; }
</style>
"""
html_with_column_widths = css_set_column_width + html_table
with open("table_with_set_column_widths.html", "w") as file:
   file.write(html_with_column_widths)

 

Table Borders and Spacing

This section will guide you through adjusting cell padding and margins in a Pandas DataFrame’s HTML table.

import pandas as pd
data = {
    'Plan Name': ['Unlimited Data', 'Family Pack', 'Budget Plan', 'Business Plan'],
    'Monthly Cost ($)': [50, 80, 30, 100],
    'Data Limit (GB)': [None, 100, 10, 200]
}
df = pd.DataFrame(data)
styled_df = df.style.set_table_styles([
    {'selector': 'th, td',
     'props': [('padding', '10px'), ('margin', '5px'), ('border', '1px solid black')]},
    {'selector': 'table',
     'props': [('border-collapse', 'separate'), ('border-spacing', '15px 5px')]},
], overwrite=False)
html_styled = styled_df.to_html(escape=False)
with open("padded_margins_table.html", "w") as file:
    file.write(html_styled)

Each cell is distinctly separated with adjusted padding and margins.

 

Styling with CSS Stylesheets

Let’s explore how you can use an external CSS stylesheet to style Pandas HTML tables.

First, create a CSS file, named table_styles.css, with your desired styles:

/* table_styles.css */
.table-style {
    border-collapse: collapse;
    width: 100%;
}
.table-style th, .table-style td {
    border: 1px solid #ddd;
    padding: 8px;
    text-align: center;
}
.table-style th {
    background-color: #f2f2f2;
    color: black;
}
/* Add more styles as needed */

Next, use this stylesheet in your Python script to style the DataFrame:

import pandas as pd
data = {
    'Service': ['Internet', 'Mobile', 'Cable TV', 'Landline'],
    'Users': [15000, 20000, 10000, 5000],
    'Revenue ($)': [300000, 450000, 120000, 80000]
}
df = pd.DataFrame(data)
html_table = df.to_html(classes='table-style', escape=False)

# Link to the external CSS file
html_linked_css = f"""
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="table_styles.css">
</head>
<body>
{html_table}
</body>
</html>
"""
with open("styled_with_external_css.html", "w") as file:
    file.write(html_linked_css)

This HTML file is linked to the external CSS stylesheet table_styles.css, which applies the defined styles to the DataFrame’s table.

 

Using CSS Frameworks Like Bootstrap

First, ensure you have Bootstrap included in your HTML. You can use a CDN link to include Bootstrap:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">

Next, apply Bootstrap classes to your DataFrame:

import pandas as pd
data = {
    'Plan Name': ['Unlimited Data', 'Family Pack', 'Budget Plan', 'Business Plan'],
    'Monthly Cost ($)': [50, 80, 30, 100],
    'Data Limit (GB)': [None, 100, 10, 200]
}
df = pd.DataFrame(data)
html_table = df.to_html(classes=['table', 'table-hover', 'table-striped'], escape=False)

# Create complete HTML with Bootstrap
html_with_bootstrap = f"""
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    {html_table}
</div>
</body>
</html>
"""
with open("bootstrap_styled_table.html", "w") as file:
    file.write(html_with_bootstrap)

The resulting HTML table is styled using Bootstrap classes like table, table-hover, and table-striped.

 

Make Pretty HTML Table

Creating visually appealing HTML tables directly from a Pandas DataFrame can be significantly simplified using the pretty_html_table library.

This library provides a straightforward way to transform a DataFrame into a nicely formatted HTML table with minimal coding effort.

First, you need to install the pretty_html_table library. You can do this using pip:

pip install pretty_html_table

Once installed, you can use it to convert a DataFrame into an HTML table:

import pandas as pd
from pretty_html_table import build_table
data = {
    'Plan Name': ['Unlimited Data', 'Family Pack', 'Budget Plan', 'Business Plan'],
    'Monthly Cost ($)': [50, 80, 30, 100],
    'Data Limit (GB)': ['Unlimited', 100, 10, 200]
}
df = pd.DataFrame(data)
pretty_html = build_table(df, 'blue_light')
with open('pretty_table.html', 'w') as f:
    f.write(pretty_html)

pretty_html_table offers a variety of built-in color themes, like 'blue_light' used above.

 

Hiding Columns and Rows

Let’s demonstrate how to use CSS to hide columns and rows in the HTML representation of our telecom company dataset.

Hiding Columns Using CSS

Suppose you want to hide the ‘Data Limit (GB)’ column in your table:

import pandas as pd
data = {
    'Plan Name': ['Unlimited Data', 'Family Pack', 'Budget Plan', 'Business Plan'],
    'Monthly Cost ($)': [50, 80, 30, 100],
    'Data Limit (GB)': [None, 100, 10, 200]
}
df = pd.DataFrame(data)
html_table = df.to_html(classes='table-style', escape=False)

# CSS to hide the 'Data Limit (GB)' column (third column)
css_to_hide_column = """
<style>
    .table-style td:nth-child(3),
    .table-style th:nth-child(3) {
        display: none;
    }
</style>
"""
html_with_css = css_to_hide_column + html_table

Hiding Rows Using CSS

Similarly, if you want to hide a specific row, such as rows with ‘Monthly Cost ($)’ greater than 80:

rows_to_hide = df.index[df['Monthly Cost ($)'] > 80].tolist()
css_to_hide_rows = "<style>" + " ".join([f".table-style tr:nth-child({row+1}) {{ display: none; }}" for row in rows_to_hide]) + "</style>"
html_with_css_rows_hidden = css_to_hide_rows + html_table
Leave a Reply

Your email address will not be published. Required fields are marked *