Essential Techniques to Style Pandas DataFrames

How to Effectively Communicate Data with Tables (including Cheat Sheet)

Style Pandas DataFrames in Python: format numbers, apply color gradients, highlight values, and use conditional formatting to communicate data effectively.
Towards Data Science Archive
Published

June 27, 2022

One unstyled panda and three styled pandas: one with various colors, one with a gradient background, one with a highlight.

Styled Pandas (Image by author)

At the end of your data analysis, you need to decide how to communicate your findings. Tables can be more suitable than graphs for communicating data when you need your audience to look up individual precise values and compare them to other values. However, tables contain a lot of information that your audience processes by reading, which makes it difficult for your audience to understand your message right away. Random design of the table, such as too many colors, bold borders, or too much information, can additionally distract your audience. However, purposeful usage of formatting and styling can guide your audience’s attention to the most important number in a table.

Purposeful usage of formatting and styling can guide your audience’s attention to the most important number in a table.

DataFrames from the pandas library are great to visualize data as tables in Python. Additionally, the pandas library provides methods to format and style the DataFrame via the style attribute. Therefore, this article discusses essential techniques to format and style pandas DataFrames to effectively communicate data.

If you want to play around with the techniques describes in this article, you can download or fork this article’s code including the example dataset from my related Kaggle Notebook.

For this tutorial, we will be using the following small fictional dataset:

Unstyled pandas DataFrame of Fictional Sample Dataset (Image by author from Kaggle)

Global Display Options

Before you get started with customizing the visualizations for individual DataFrames, you can adjust the global display behavior of pandas with the .set_option() method [1]. Two common tasks you can handle are:

  • displaying all columns of a DataFrame and
  • adjusting the width of a DataFrame column.

When your DataFrame has too many columns, pandas does not render all columns but instead hides columns in the middle. To force pandas to display all columns, you can set:

pd.set_option("display.max_columns", None)

When you are working with long texts, pandas truncates the text in the column. To force pandas to display the full column contents by increasing the column width, you can set:

pd.set_option("display.max_colwidth", None)

General Tips

The DataFrame’s style attribute, returns an object of the class Styler. This class contains various formatting and styling methods. The following tips apply to all methods of the Styler object.

Multiple Stylings

You can combine multiple stylings by chaining multiple methods together.

E.g. df.style.set_caption(...).format(...).bar(...).set_properties(...)

Column-wise vs. Row-wise Styling

By default, the styling is applied column-wise (axis = 0).

df.style.highlight_max() # default is axis = 0

Highlight column-wise maximum with ‘axis = 0’ (Image by author from Kaggle)

If you want to apply the styling row-wise, use axis = 1 in the properties instead.

df.style.highlight_max(axis = 1))

Highlight row-wise maximum with ‘axis = 1’ (Image by author from Kaggle)

Styling Only a Subset

By default, the styling methods are applied to all columns.

df.style.background_gradient()

Background gradient applied to all columns (Image by author from Kaggle)

If you want to apply the stylings only to one column or a selected subset of columns, use the subset parameter.

df.style.background_gradient(subset = ["A", "D"]))

Background gradient applied to columns A and D (Image by author from Kaggle)

Formatting

Before we begin with any specific coloring, let’s have a look at some fundamental formatting techniques to make your DataFrame look more polished.

Caption

Adding a caption to a table is essential to provide some context to your audience. You can add the caption to the DataFrame with the .set_caption() method.

df.style.set_caption("Caption Text")

Caption added above DataFrame (Image by author from Kaggle)

Renaming Columns

If the column names are variable names or abbreviated, it might not be clear to your audience what data they are looking at. Giving the columns intuitive column names, can support your audience’s understanding of the data.

There are two options to rename your columns:

  • Renaming all columns at once
  • Renaming only a subset of columns

If you need to work with the DataFrame later on, it might make sense to create a copy of the DataFrame for visualization purposes only.

# Create a copy of the DataFrame for visualization purposes  
df_viz = df.copy()

You can rename all columns at once by changing the columns attribute:

# Rename all columns  
df_viz.columns = ["New Column Name A",   
                  "New Column Name B",   
                  "New Column Name C",   
                  "New Column Name D"]

Rename all columns of DataFrame (Image by author from Kaggle)

Or you can rename only a subset of columns with the .rename() method and a dictionary.

# Rename selection of columns  
df_viz.rename(columns = {"A" : "New Column Name A",   
                         "B" : "New Column Name B"},   
              inplace = True)

Rename only a subset of columns (Image by author from Kaggle)

Hiding the Index

Does the index add any valuable information? If not, you can hide the index with the .hide_index() method.

df.style.hide_index()

Hidden Index (Image by author from Kaggle)

Format Columns

Adding thousands-separators or truncating the floating-point numbers to fewer decimal places can increase the readability of your DataFrame. For this purpose, the Styler object can distinguish the display values from the actual values.

By using the .format() method you can manipulate the display values according to a format spec string [3]. You can even add a unit before or after the number as part of the formatting.

df.style.format({"A" : "{:,.0f}",  
                 "B" : "{:d} $",  
                 "C" : "{:.3f}",  
                 "D" : "{:.2f}"})

Columns formatted with thousands-separator and custom number of floating-points (Image by author from Kaggle)

However, to not disturb the attention, I would recommend putting the unit in square brackets in the column name, e.g., “Salary [$]”.

Styling Properties

Sometimes, all you want to do might be to highlight a single column in the DataFrame by adjusting the background and font color. For this purpose, you can use the .set_properties() method to adjust the relevant CSS properties of the DataFrame such as colors, fonts, borders, etc.

df.style.set_properties(subset = ["C"],  
                        **{"background-color": "lightblue",    
                           "color" : "white",  
                           "border" : "0.5px solid white"})

Highlighted column (Image by author from Kaggle)

Built-in Styling

The Style class has some built-in methods for common styling tasks.

Highlighting

Highlighting individual cells is an easy way to guide your audience’s attention to what you want to show. Common values you might want to highlight are minimum, maximum, and null values. For these cases, you can use the respective built-in methods.

You can adjust the highlight color with the parameter color for minimum and maximum highlighting and nullcolor for null highlighting.

df.style.highlight_null(null_color = "yellow")

Highlighted null value (Image by author from Kaggle)

If you want to highlight both minimum and maximum values, you can do so by chaining both functions together.

df.style.highlight_min(color = "red")\  
        .highlight_max(color = "green")

Highlighted minimum and maximum values (Image by author from Kaggle)

Gradients

Adding gradient styles can help the audience understand the relationship of the numerical values within the table, a single column or a single row. For example, gradients can indicate whether a value is large or small, positive or negative, or even good or bad.

There are also two techniques to add gradients to the DataFrame:

  1. You can apply gradient styles either to the text or
  2. you can apply gradient styles to the background [2].

With the cmap parameter and vmin and vmax you can set the properties of the gradient. The cmap sets the used colormap and vmin and vmax set the relevant start and end values.

You can apply gradients to the text with the .text_gradient() method:

df.style.text_gradient(subset = ["D"],   
                       cmap = "RdYlGn",   
                       vmin = -1,   
                       vmax = 1)

Gradient style applies to text of column D (Image by author from Kaggle)

Or you can apply gradients to the background with the .background_gradient() method:

df.style.background_gradient(subset = ["D"],   
                             cmap = "RdYlGn",   
                             vmin = -1,   
                             vmax = 1)

Gradient style applied to background of column D (Image by author from Kaggle)

Bars

Another way of visualizing the relationship and order within a column or a row is to draw bars in the cell’s background [2].

Again, there are two essential techniques to utilize bars in your DataFrames:

  1. The straightforward application is to use a standard uni-colored bar.
  2. Or you can also create bi-colored bar charts from a mid-point.

For the standard bar chart, simple use the .bar() method as follows:

df.style.bar(subset = ["A"],   
             color = "lightblue",   
             vmin = 0)

Bars added to background of column A (Image by author from Kaggle)

To create bi-colored bar charts set the alignment to mid and define colors for the lower and upper values. When using this method, I recommend combining it with some borders to increase the readbility.

df.style.bar(subset = ["D"],   
             align = "mid",   
             color = ["salmon", "lightgreen"])\  
        .set_properties(**{'border': '0.5px solid black'})

Positive and negative value bars added to background of column D (Image by author from Kaggle)

Custom Styling

If the built-in styling methods are not sufficient for your needs, you can write your own styling function and apply it to the DataFrame. You can either apply styling element-wise with the .applymap() method or column- or row-wise with the .apply() method [2].

A popular example of this is to display negative values of a DataFrame in red color as shown below:

def custom_styling(val):  
    color = "red" if val < 0 else "black"  
    return f"color: {color}"df.style.applymap(custom_styling)

Highlight negative values in red (Image by author from Kaggle)

Export to Excel

If you need your styled DataFrame in Excel format, you can export it including its styling and formatting to an .xlsx file [3]. For this, you need to have the openpyxl package installed.

pip install openpyxl

To export the DataFrame, you can apply the styling and formatting to your DataFrame as usual and follow it with the .to_excel() method.

df.style.background_gradient(subset = ["D"],   
                             cmap = "RdYlGn",   
                             vmin = -1,   
                             vmax = 1)\  
        .to_excel("styled.xlsx", engine = "openpyxl")

Conclusion

The pandas DataFrame’s style attribute enables you to format and style a DataFrame to effectively communicate the insights from your data analysis. This article discussed essential techniques to style pandas DataFrames including how to set global display options, format and customize stylings, and even how to export your DataFrame to Excel format. There are many more styling and formatting options available on the pandas documentation.

For further experimentation, you can download or fork this article’s code including the example dataset from my related Kaggle Notebook.

Below I have summarized all tips in a cheat sheet:

Cheat Sheet of Essential Formatting and Styling Techniques for pandas DataFrames (Image by author).

References

[1] “pandas 1.4.2 documentation”, “Options and settings.” pandas.pydata.org. https://pandas.pydata.org/docs/user_guide/options.html (accessed June 13, 2022)

[2] “pandas 1.4.2 documentation”, “Style.” pandas.pydata.org. https://pandas.pydata.org/docs/reference/style.html (accessed June 16, 2022)

[3] “pandas 1.4.2 documentation”, “Table Visualization.” pandas.pydata.org. https://pandas.pydata.org/docs/user_guide/style.html (accessed June 16, 2022)

[4] “Python”, “string – Common string operations.” python.org. https://docs.python.org/3/library/string.html#formatspec (accessed June 13, 2022)


This blog was originally published on Towards Data Science on Jun 27, 2022 and moved to this site on Feb 1, 2026.

Back to top