altair
altair copied to clipboard
Improve the syntax for conditions with multiple predicates
Questioned in SO: How to create an altair condition with three or more choices [duplicate] and SO: Combine hover and click selections in Altair and surfaced in https://github.com/altair-viz/altair/pull/2756
It is currently possible to write a condition with single predicate:
import altair as alt
from vega_datasets import data
cars = data.cars.url
base = alt.Chart(cars).mark_tick().encode(x='Miles_per_Gallon:Q')
# condition with single predicate
base.encode(color=alt.condition(
alt.datum.Origin == 'Europe',
alt.value('green'), # when true
alt.value('red') # when false
)
)

And one can combine multiple selections into a single predicate as is written here: https://altair-viz.github.io/user_guide/interactions.html#composing-multiple-selections
To combine multiple predicates within a single condition one can define a dict with a list of conditions as such:
# condition with multiple predicates
color_condition = {
"condition": [
{"test": "datum.Origin === 'Europe'", "value": "green"},
{"test": "datum.Origin === 'Japan'", "value": "blue"},
],
"value": "red",
}
base.encode(
color=color_condition
)

But using an alt.condition() this is not possible.
Maybe something as such should be supported:?
base.encode(color=alt.condition(
predicate=[
alt.pred(expr=alt.datum.Origin == "Europe", if_true=alt.value("green")),
alt.pred(expr=alt.datum.Origin == "Japan", if_true=alt.value("blue")),
],
if_false=alt.value("red")
)
)
@joelostblom do you still have a ideas for this? I like to use this to combine a highlight and click condition. Something quite common, but the approach is not clear yet.
We also can also implement a list of conditions, like [alt.condition(), alt.condition()], or a new alt.conditions() (plural) or change the current alt.condition() so it by defaults support multiple predicates or do something as alt.condition() + alt.condition().
Edit; Or
alt.condition() * alt.condition()
Hmm I don't really have a good idea of what is prefereable here, other than in terms of what I would find nice to type myself, which I think would be similar to the last example in your first comment, something like this:
base.encode(
color=alt.condition([
(alt.datum.Origin == "Europe", alt.value("green")),
(alt.datum.Origin == "Japan", alt.value("blue"))
],
alt.value("red")
)
Partly related https://github.com/altair-viz/altair/issues/695