col_numeric()

Create a color-mapping function for continuous numeric values.

Usage

Source

col_numeric(
    palette=None,
    domain=None,
    na_color=None,
    reverse=False,
    truncate=False,
)

The col_numeric() helper returns a function that linearly maps numeric values onto a color palette (interpolating between the palette’s colors). The returned function is designed to be passed to the fn= argument of data_color(), but it can be called on any list of values.

Parameters

palette: str | list[str] | None = None

The colors to interpolate between. This can be a list of colors (as hexadecimal values or color names) or the name of a ColorBrewer or viridis palette (see data_color() for the available names). If None, then a default palette will be used.

domain: list[int] | list[float] | None = None

The range of values to map onto the palette, given as [min, max]. Values outside of this range receive the missing-value color (unless truncate=True). If None, then the domain is taken from the range of the (non-missing) values supplied to the returned function each time it is called.

na_color: str | None = None

The color to use for missing values and values outside of the domain. If None, then the returned function gives None for those values, which lets data_color() apply its own na_color= color.

reverse: bool = False

Should the order of the palette colors be reversed?

truncate: bool = False
If True, then values outside of the domain are treated as the nearest end of the domain, so they receive the first or last color of the palette. If False (the default), then they receive the missing-value color.

Returns

Callable[[list[Any]], list[str | None]]
A function that takes a list of numeric values and returns a list of hexadecimal colors.

Examples

A diverging palette with a domain centered on zero colors negative values increasingly red and positive values increasingly green, the further they are from zero:

import pandas as pd
from great_tables import GT, col_numeric

df = pd.DataFrame(
    {
        "region": ["North", "South", "East", "West", "Central"],
        "change": [12.5, -8.1, 0.0, 3.2, -1.0],
    }
)

GT(df).data_color(
    columns="change",
    fn=col_numeric(palette=["#D7191C", "white", "#1A9641"], domain=[-15, 15]),
)
region change
North 12.5
South -8.1
East 0.0
West 3.2
Central -1.0

Because col_numeric() returns an ordinary function, it can be composed with other logic. Here, the domain is made symmetric around zero based on the largest absolute value in the column:

def red_white_green(vals):
    m = max(abs(x) for x in vals if not pd.isna(x))
    return col_numeric(palette=["#D7191C", "white", "#1A9641"], domain=[-m, m])(vals)

GT(df).data_color(columns="change", fn=red_white_green)
region change
North 12.5
South -8.1
East 0.0
West 3.2
Central -1.0

With a narrower domain, truncate=True saturates the colors of values beyond its limits rather than leaving them uncolored. Here, anything above 5 is fully green and anything below -5 is fully red:

GT(df).data_color(
    columns="change",
    fn=col_numeric(palette=["#D7191C", "white", "#1A9641"], domain=[-5, 5], truncate=True),
)
region change
North 12.5
South -8.1
East 0.0
West 3.2
Central -1.0