Styling tricks in Great Tables

python
pandas
polars
gt
Author

Jerry Wu

Published

May 26, 2025

This post highlights a powerful yet underused feature in Great Tables: using existing columns to style the table body via from_column().

Let’s say you have the following Polars DataFrame df:

import polars as pl
from great_tables import GT, from_column, loc, style
from great_tables.data import films


df_style = pl.DataFrame(
    {
        "color": ["papayawhip", "lightblue", "lightgreen"],
        "size": ["small", "x-large", "medium"],
        "weight": ["normal", "bold", "lighter"],
        "align": ["right", "center", "left"],
    }
)

columns = ["year", "title", "run_time"]

df = pl.concat(
    [
        pl.from_pandas(films.head(3).loc[:, columns]),
        df_style,
    ],
    how="horizontal",
)

print(df)
shape: (3, 7)
┌──────┬───────────────────────────┬──────────┬────────────┬─────────┬─────────┬────────┐
│ year ┆ title                     ┆ run_time ┆ color      ┆ size    ┆ weight  ┆ align  │
│ ---  ┆ ---                       ┆ ---      ┆ ---        ┆ ---     ┆ ---     ┆ ---    │
│ i64  ┆ str                       ┆ str      ┆ str        ┆ str     ┆ str     ┆ str    │
╞══════╪═══════════════════════════╪══════════╪════════════╪═════════╪═════════╪════════╡
│ 1946 ┆ The Lovers                ┆ 1h 30m   ┆ papayawhip ┆ small   ┆ normal  ┆ right  │
│ 1946 ┆ Anna and the King of Siam ┆ 2h 8m    ┆ lightblue  ┆ x-large ┆ bold    ┆ center │
│ 1946 ┆ Blood and Fire            ┆ 1h 40m   ┆ lightgreen ┆ medium  ┆ lighter ┆ left   │
└──────┴───────────────────────────┴──────────┴────────────┴─────────┴─────────┴────────┘

The color, size, weight, and align columns contain style-related metadata. We can use from_column() to map this metadata to four styling options provided by Great Tables—style.fill(), style.text(), style.borders(), and style.css()—all of which are built on the internal CellStyle class.

(
    GT(df)
    .tab_style(
        style=[
            style.fill(color=from_column("color")),
            style.text(
                size=from_column("size"),
                weight=from_column("weight"),
                align=from_column("align"),
            ),
        ],
        locations=loc.body(columns),
    )
    .cols_hide(df_style.columns)
    .opt_stylize(style=6, color="gray")
)
year title run_time
1946 The Lovers 1h 30m
1946 Anna and the King of Siam 2h 8m
1946 Blood and Fire 1h 40m

One last note: from_column() works with both Pandas and Polars DataFrames. For Polars users, you can also pass expressions directly without wrapping them in from_column(). The following code produces the same styled table as shown above:

(
    GT(df)
    .tab_style(
        style=[
            style.fill(color=pl.col("color")),
            style.text(
                size=pl.col("size"), weight=pl.col("weight"), align=pl.col("align")
            ),
        ],
        locations=loc.body(columns),
    )
    .cols_hide(df_style.columns)
    .opt_stylize(style=6, color="gray")
)
Disclaimer

This post was drafted by me, with AI assistance to refine the content.