Skip to content

Python Pandas: How to Apply Custom Formats to Table Rows (in Jupyter Notebook)

Learn how to use Pandas Styler API to apply conditional CSS formatting to DataFrame rows in Jupyter Notebooks, including row highlighting for failed statuses, grade traffic lights, and avoiding shape mismatch errors.

In Python data analysis, presenting raw data can often be overwhelming. Visual cues, such as highlighting specific rows based on criteria (e.g., high risk, failing grades, or outliers), significantly improve readability. The primary tool for this in the Python ecosystem is the Pandas Styler API.

This guide explains how to apply custom CSS styles to DataFrame rows based on data conditions using pandas.DataFrame.style.

Understanding the Pandas Styler

Pandas DataFrames have a .style property that returns a Styler object. This object renders the data as HTML (for Jupyter Notebooks or web reports) and allows you to apply CSS.

To style rows, we use the .apply() method with axis=1.

  • axis=0: Apply function column-wise.
  • axis=1: Apply function row-wise (this is what we want).
  • axis=None: Apply function element-wise (entire table).

Method 1: Conditional Row Highlighting

The most common use case is highlighting a row if a specific column meets a condition.

Step-by-Step Implementation:

  1. Define a function that takes a row (Series).
  2. Check the condition on a specific column.
  3. Return a list of CSS strings matching the row length.
import pandas as pd

data = {
    'Project': ['Alpha', 'Beta', 'Gamma', 'Delta'],
    'Status': ['Complete', 'In Progress', 'Failed', 'Complete'],
    'Budget': [10000, 25000, 5000, 12000]
}
df = pd.DataFrame(data)

def highlight_failed_rows(row):
    if row['Status'] == 'Failed':
        return ['background-color: #ffcccc; color: red'] * len(row)
    else:
        return [''] * len(row)

styled_df = df.style.apply(highlight_failed_rows, axis=1)

display(styled_df) 

Result: The row for Project "Gamma" will have a light red background and red text.

Method 2: Multi-Condition (Gradient) Styling

You can apply complex logic, such as a traffic light system, by expanding the if/elif/else logic within your styling function.

import pandas as pd

df = pd.DataFrame({
    'Student': ['Alice', 'Bob', 'Charlie', 'David'],
    'Score': [95, 55, 75, 88]
})

def grade_traffic_light(row):
    score = row['Score']
    
    green = 'background-color: #d4edda; color: #155724' # Pass
    yellow = 'background-color: #fff3cd; color: #856404' # Average
    red = 'background-color: #f8d7da; color: #721c24'    # Fail
    default = ''
    
    if score >= 90:
        style = green
    elif score >= 60:
        style = yellow
    else:
        style = red
        
    return [style] * len(row)

styled_report = df.style.apply(grade_traffic_light, axis=1)
display(styled_report)

Common Error: Shape Mismatch

A frequent ValueError occurs when the styling function returns a single string instead of a list, or a list of the wrong length. Pandas expects the returned styles to map 1-to-1 with the cells in that row.

Example of Error

import pandas as pd

df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})

def broken_highlighter(row):
    if row['A'] > 1:
        return 'background-color: yellow'
    return ''

try:
    df.style.apply(broken_highlighter, axis=1).to_html()
except Exception as e:
    print(f"Error: {e}")

Output:

Error: Function returned scalar: 'background-color: yellow'
... expecting list-like with length 2

Solution

Ensure the return value is a list multiplied by len(row).

def fixed_highlighter(row):
    if row['A'] > 1:
        return ['background-color: yellow'] * len(row)
    return [''] * len(row)

html_output = df.style.apply(fixed_highlighter, axis=1).to_html()
print("Styling applied successfully.")

Conclusion

To apply custom formats to table rows in Python Pandas:

  1. Define a Function: Create a Python function that accepts a row (Series).
  2. Logic: Inside the function, check your data conditions (e.g., if row['val'] > 0).
  3. Return Format: Return a list of CSS strings (['style: val'] * len(row)).
  4. Apply: Use df.style.apply(func, axis=1) to render the changes.

This technique allows you to export professional, readable HTML tables or Excel sheets directly from your data analysis scripts.

Navigation