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

BUG: composing multiple selections #1707

Merged
merged 3 commits into from
Oct 1, 2019
Merged

BUG: composing multiple selections #1707

merged 3 commits into from
Oct 1, 2019

Conversation

mattijn
Copy link
Contributor

@mattijn mattijn commented Sep 26, 2019

This PR has still some issues, but it adds some documentation + inline example to compose multiple selections as discussed in #1704.

I tried to emulate the Vega-Lite example from here, but preferred to hold the ctrl-key or shift-key to separately initiate the selections.

I don't know how to make the following Vega-Lite example with bitwise operators work in Altair:

"selection": {"not": {"and": ["alex", "morgan"]}}

I tried some (eg. ~alex & ~morgan and ~[alex & morgan]), but got none working.

@jakevdp
Copy link
Collaborator

jakevdp commented Sep 26, 2019

I think ~(alex & morgan) should work (or equivalently, ~alex | ~morgan following De Morgan's law)

@jakevdp
Copy link
Collaborator

jakevdp commented Sep 26, 2019

Actually, it looks like those compound operands are not fully implemented currently.

@jakevdp
Copy link
Collaborator

jakevdp commented Sep 26, 2019

Relevant issue is #695

@mattijn
Copy link
Contributor Author

mattijn commented Sep 26, 2019

I think I got the compound operators working:

class Foo(object):
    def __init__(self, name):
        self.name = name      
    
    def __invert__(self):
        return Foo({'not': self.name})
        
    def __repr__(self):
        return str(self.name)
    
    def __or__(self, other):
        return Foo({'or': [self.name, other]})
    
    def __and__(self, other):
        return Foo({'and': [self.name, other]})


x = Foo('s1')
y = Foo('s2')
z = Foo('s3')
x | ~y
{'or': ['s1', {'not': 's2'}]}
~x | y
{'or': [{'not': 's1'}, s2]}
~x | ~y
{'or': [{'not': 's1'}, {'not': 's2'}]}
~(x & y)
{'not': {'and': ['s1', s2]}}
~z | x & ~y
{'or': [{'not': 's3'}, {'and': ['s1', {'not': 's2'}]}]}

@jakevdp
Copy link
Collaborator

jakevdp commented Sep 26, 2019

Yeah, that's how to implement them. The challenge is that the relevant classes are auto-generated, so we'll need to create wrappers in order to define the operators correctly. And there are a lot of relevant classes.

@mattijn mattijn changed the title DOC: composing multiple selections BUG: composing multiple selections Sep 27, 2019
@mattijn
Copy link
Contributor Author

mattijn commented Sep 27, 2019

I've changed the operators (__invert__, __and__, and __or__) to return instances of Selection. With this I'm able to chain the selections to invoke further operations on them.

I add some tests to verify, but (!) also had to change some tests to make all tests pass. Please have a look.

@jakevdp jakevdp merged commit c421192 into vega:master Oct 1, 2019
jakevdp added a commit that referenced this pull request Oct 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants