vega / altair

Declarative statistical visualization library for Python
https://altair-viz.github.io/
BSD 3-Clause "New" or "Revised" License
9.39k stars 795 forks source link

feat: Support `&`, `|`, `~` on all `...Predicate` classes #3668

Closed dangotbanned closed 2 weeks ago

dangotbanned commented 3 weeks ago

Resolves #695

Description

This PR enables the use of logical composition operators (&, |, ~) directly on all 12 of:

...Predicate classes

- `core.FieldEqualPredicate` - `core.FieldGTEPredicate` - `core.FieldGTPredicate` - `core.FieldLTEPredicate` - `core.FieldLTPredicate` - `core.FieldOneOfPredicate` - `core.FieldRangePredicate` - `core.FieldValidPredicate` - `core.LogicalAndPredicate` - `core.LogicalOrPredicate` - `core.LogicalNotPredicate` - `core.ParameterPredicate`

It appears this functionality has been desired for some time, but never implemented fully.

api.SelectionPredicateComposition already contained the code required to get this working - this PR moves that to core.PredicateComposition.

The change is fully backwards compatible, turning the old class into an alias (https://github.com/vega/altair/pull/3668/commits/1dc15b72c01fe47a5b87222d26258eb08b75cdea)

This also provides a cleaner solution to (https://github.com/vega/altair/pull/3664#discussion_r1823177593) - than any of the alternatives documented there

Example

import altair as alt
from vega_datasets import data

source = data.disasters()
columns_sorted = ["Drought", "Epidemic", "Earthquake", "Flood"]

base = (
    alt.Chart(source, height=200)
    .mark_line(interpolate="monotone")
    .encode(
        x=alt.X("Year:Q").axis(format="d"),
        color="Entity",
        column="Entity",
        y="sum(Deaths)",
    )
)

chart_old = base.transform_filter(
    {
        "and": [
            alt.FieldOneOfPredicate(field="Entity", oneOf=columns_sorted),
            alt.FieldRangePredicate(field="Year", range=[1900, 2000]),
        ]
    }
)

chart_new = base.transform_filter(
    alt.FieldOneOfPredicate(field="Entity", oneOf=columns_sorted)
    & alt.FieldRangePredicate(field="Year", range=[1900, 2000])
)
chart_old & chart_new
Output

![predicate-composition-dunder](https://github.com/user-attachments/assets/6f6e785e-1faa-4cc4-8226-af389eeac4c2)

User Guide

image

Tasks

Other Future Work

Related