Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composing predicates in alt.condition() is tedious #2176

Closed
dechamps opened this issue May 25, 2020 · 2 comments
Closed

Composing predicates in alt.condition() is tedious #2176

dechamps opened this issue May 25, 2020 · 2 comments
Labels

Comments

@dechamps
Copy link

dechamps commented May 25, 2020

I want to OR two predicates in an alt.condition() call.

Initially I just assumed I could use a similar syntax as for transform_filter():

(alt.Chart(data=None)
    .mark_circle()
    .encode(color=alt.condition({'or': [
                    alt.FieldEqualPredicate(field='field1', equal='value1'),
                    alt.FieldEqualPredicate(field='field2', equal='value2'),
                ]}, alt.value('red'), alt.value('green'))))

But that doesn't work:

SchemaValidationError: Invalid specification
        altair.vegalite.v4.schema.channels.ColorValue, validating 'additionalProperties'
        Additional properties are not allowed ('or' was unexpected)

Then I thought maybe the operators would work:

(alt.Chart(data=None)
    .mark_circle()
    .encode(color=alt.condition(
            alt.FieldEqualPredicate(field='field1', equal='value1') |
            alt.FieldEqualPredicate(field='field2', equal='value2'),
        alt.value('red'), alt.value('green'))))

But nope:

TypeError: unsupported operand type(s) for |: 'FieldEqualPredicate' and 'FieldEqualPredicate'

After fumbling around in the dark for some time, this is the best I came up with:

(alt.Chart(data=None)
    .mark_circle()
    .encode(color=alt.condition(alt.LogicalOrPredicate(**{'or': [
                    alt.FieldEqualPredicate(field='field1', equal='value1'),
                    alt.FieldEqualPredicate(field='field2', equal='value2'),
                ]}), alt.value('red'), alt.value('green'))))

This actually works, but the syntax is contrived and this approach doesn't seem documented. Should the API be improved, or am I missing something here?

@jakevdp
Copy link
Collaborator

jakevdp commented May 25, 2020

That works; a clearer option is probably this:

(alt.Chart(data=None)
    .mark_circle()
    .encode(color=alt.condition(
        (alt.datum.field1 == 'value1') | (alt.datum.field2 == 'value2'),
        alt.value('red'), alt.value('green')))
)

Adding operator support to other predicates is tracked here: #695

But it hasn't been a priority because vega expressions like the one above cover the use-cases pretty well.

@joelostblom
Copy link
Contributor

@dechamps I am going through Altair issues to find those that have been resolved and can be closed. It looks to me like this issue has been solved so I am closing it, but please feel free to reopen and add a comment if there is something you don't think is resolved yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants