altair icon indicating copy to clipboard operation
altair copied to clipboard

More convenient syntax instead of FieldOneOfPredicate

Open joelostblom opened this issue 2 years ago • 10 comments

Writing a condition that matches a single value in relatively straightforward:

import altair as alt
from vega_datasets import data


source = data.cars()
alt.Chart(source).mark_point().encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color=alt.condition(
        alt.datum.Origin == 'Japan',
        alt.value('red'),
        alt.value('grey')
    )
)

But when we want to match multiple values, the alt.datum.Origin == 'Japan', needs to be replaced with the notably more compllicated:

        alt.FieldOneOfPredicate(
            'Origin',
            ['Japan', 'Europe']
        ),

It would be nice to support the in operator here and allow the syntax to just be alt.datum.Origin in ['Japan', 'Europe']. I haven't looked into the change necessary to make this happen but noting it down as something to revisit in the future.

joelostblom avatar Oct 26 '23 01:10 joelostblom

I think that you would need a custom Altair list instead of using a python list to control this behaviour in the predicate. You could add a custom magic method for the membership operator (eg. __contains__) to the OperatorMixin, but the equivalent in and not in membership operators will only be applied to the right-hand-side operand and not on the left-hand-side operand. Basically the list decide what it contains and since this is a python list it will return a boolean.

mattijn avatar Oct 28 '23 22:10 mattijn

...the equivalent in and not in membership operators will only be applied to the right-hand-side operand and not on the left-hand-side operand. Basically the list decide what it contains and since this is a python list it will return a boolean.

I was wondering about this. What made me think that it might be possible was that we do use the standard Python operators for the other comparisons, but I hear that this might not work the same for the in operator. I don't fully understand why it would only be applied to the right-hand side from just skimming the code, but I will try to have a closer look at that section of the code base in the future. Thanks for pointing this out and linking to where the logic is!

joelostblom avatar Oct 28 '23 22:10 joelostblom