#4084·altair

[feat]: Union channels field with the `|` operator

Author: AntyosCreated Jul 17, 2026Updated Sep 11, 2026
Labelsenhancement

What is your suggestion?

I often find myself wanting to apply some default parameters to field channels in my functions. For example:

python
import altair as alt

def plot_something(data: alt.ChartDataType, x: alt.X):
    default_x_scale = alt.X(scale=alt.Scale(paddingOuter=0.1))

    # Update X with default attributes
    x = alt.X.from_dict({**x.to_dict(), **default_x_scale.to_dict()})

    return alt.Chart(data).mark_bar().encode(
        x=x,
        y=alt.Y("count()", title="Count"),
    )

Note, in this example, the type hint is flagged because X.to_dict() inherits from FieldChannelMixin.to_dict() which can sometimes return a list[dict] which I'm not sure how or why, but that doesn't change my point.

Since these field channels are basically Mappings, I think a more convenient syntax would be to use the | operator like a dictionary union, e.g. default_x_scale | x

python
import altair as alt

def plot_something(data: alt.ChartDataType, x: alt.X):
    default_x_scale = alt.X(scale=alt.Scale(paddingOuter=0.1))

    # More convenient union syntax
    x = default_x_scale | x

    return alt.Chart(data).mark_bar().encode(
        x=x,
        y=alt.Y("count()", title="Count"),
    )

Have you considered any alternative solutions?

I have already implemented a version of this in my own code:

python
def schema_union[T: alt.SchemaBase](
    schema: T, *other: alt.typing.Optional[T | Mapping], validate: bool = False
) -> T:
    """Return the union of altair schemas."""
    schema_dict = schema.to_dict()
    for o in other:
        if not o:
            continue
        elif isinstance(o, Mapping):
            schema_dict |= o
        elif isinstance(o, type(schema)):
            schema_dict |= o.to_dict()
        else:
            raise TypeError(f"Unsupported encoding type: {type(o)}")
    return type(schema).from_dict(**schema_dict, validate=validate)

But I think it would be more convenient to have this as a overload of the __or__ methods for the channel mixins.