docs: when-then-otherwise examples#3492
Conversation
when-then-otherwise exampleswhen-then-otherwise examples
Wasn't picked up in vega#3480
Adapted from the final example in https://vega.github.io/vega-lite/docs/condition.html
Covers everything apart from chained when
when-then-otherwise exampleswhen-then-otherwise examples
|
Thanks! This looks great. I was expecting these examples to be around here: https://altair-viz.github.io/user_guide/interactions.html#conditions-filters, but the examples in this PR are part of the docstrings, which is very nice too! We should have more of these. Will add a note to #3500. I noticed when playing with this that I agree with your suggestion that it would be nice to have a Regarding, your three linked comments from original PR. I don't have clear insight on these either. I don't think it is necessary to use intersphinx, but a reference to the polars docs page of the |
Now all link to docs, rather than source code vega#3492 (comment)
Thank you for reviewing, but my bad for misunderstanding the assignment @mattijn Hopefully they will make writing the User Guide parts easier in #3500, since most of the examples already produce a valid chart.
For reference, following The
|
|
@mattijn are we good to go with this one? Sorry I can't seem to request a review |
Co-authored-by: Mattijn van Hoek <mattijn@gmail.com>
mattijn
left a comment
There was a problem hiding this comment.
Looks great. One suggested change.
I like the examples. Really clean.
# Simple conditions may be expressed without defining a default
import altair as alt
from vega_datasets import data
source = data.movies()
predicate = (alt.datum.IMDB_Rating == None) | (alt.datum.Rotten_Tomatoes_Rating == None)
alt.Chart(source).mark_point(invalid=None).encode(
x="IMDB_Rating:Q",
y="Rotten_Tomatoes_Rating:Q",
color=alt.when(predicate).then(alt.value("grey")),
)
# Points outside of `brush` will not appear highlighted
import altair as alt
from vega_datasets import data
source = data.cars()
brush = alt.selection_interval()
color = alt.when(brush).then("Origin:N").otherwise(alt.value("grey"))
alt.Chart(source).mark_point().encode(
x="Horsepower:Q",
y="Miles_per_Gallon:Q",
color=color,
).add_params(brush)
# Chain calls to express precise queries
import altair as alt
from vega_datasets import data
source = data.cars()
color = (
alt.when(alt.datum.Miles_per_Gallon >= 30, Origin="Europe")
.then(alt.value("crimson"))
.when(alt.datum.Horsepower > 150)
.then(alt.value("goldenrod"))
.otherwise(alt.value("grey"))
)
alt.Chart(source).mark_point().encode(x="Horsepower", y="Miles_per_Gallon", color=color)
# Multiple conditions with an implicit default
import altair as alt
from vega_datasets import data
source = data.movies()
predicate = (alt.datum.IMDB_Rating == None) | (alt.datum.Rotten_Tomatoes_Rating == None)
color = (
alt.when(predicate)
.then(alt.value("grey"))
.when(alt.datum.IMDB_Votes < 5000)
.then(alt.value("lightblue"))
)
alt.Chart(source).mark_point(invalid=None).encode(
x="IMDB_Rating:Q", y="Rotten_Tomatoes_Rating:Q", color=color
)
# Setting up a common chart
import altair as alt
from vega_datasets import data
source = data.cars()
brush = alt.selection_interval()
points = (
alt.Chart(source)
.mark_point()
.encode(x="Horsepower", y="Miles_per_Gallon")
.add_params(brush)
)
points
# Basic `if-then-else` conditions translate directly to `when-then-otherwise`
points.encode(color=alt.when(brush).then("Origin").otherwise(alt.value("lightgray")))
# Omitting the `.otherwise()` clause will use the channel default instead
points.encode(color=alt.when(brush).then("Origin"))
# Predicates passed as positional arguments will be reduced with `&`
points.encode(
color=alt.when(
brush, (alt.datum.Miles_per_Gallon >= 30) | (alt.datum.Horsepower >= 130)
)
.then("Origin")
.otherwise(alt.value("lightgray"))
)
# Using keyword-argument `constraints` can simplify compositions like
verbose_composition = (
(alt.datum.Name == "Name_1")
& (alt.datum.Color == "Green")
& (alt.datum.Age == 25)
& (alt.datum.StartDate == "2000-10-01")
)
when_verbose = alt.when(verbose_composition)
# To
when_concise = alt.when(Name="Name_1", Color="Green", Age=25, StartDate="2000-10-01")|
Thanks @mattijn for the review and well spotted on the missing Seeing them all together in #3492 (review) really looks like this will fit into the User Guide nicely |
|
Yes! Beautiful new addition to the Altair library! Well done @dangotbanned! |
* ci(ruff): Add `ANN` rules for `api.py` only To highlight all the missing annotations to fix and autofix `None` return * feat(typing): Complete annotations for most `api` functions Excluding `*args` on `ChartType` wrappers. They need to be defined in alignment in multiple places, which is more complex * feat(typing): Annotate more expr/params in `api` * feat(typing): Various changes to enforce `dict[str, Any]` instead of `dict` Among these, many locations already assume `str` keys in the implementation - without checking * feat(typing): Misc minor method annotations * feat(typing): Use `ChartType` in all `ChartType` dunder methods * fix(ruff): Ignore some `ANN` rules that won't be fixed * chore: add pyright ignore from #3492 * feat(typing): Improve `ChartType` constructor/factory annotations * feat(typing): Annotate remaining functions in `api` * feat(typing): Complete `RepeatChart` annotations * fix(typing): Resolve Liskov violations ``` altair\vegalite\v5\api.py:4368: error: Argument 1 of "__iadd__" is incompatible with "__add__" of supertype "TopLevelMixin"; supertype defines the argument type as "Chart | RepeatChart | ConcatChart | HConcatChart | VConcatChart | FacetChart | LayerChart" [override] def __iadd__(self, other: LayerChart | Chart) -> Self: ^~~~~~~~~~~~~~~~~~~~~~~~~ altair\vegalite\v5\api.py:4368: note: This violates the Liskov substitution principle altair\vegalite\v5\api.py:4368: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides altair\vegalite\v5\api.py:4376: error: Argument 1 of "__add__" is incompatible with supertype "TopLevelMixin"; supertype defines the argument type as "Chart | RepeatChart | ConcatChart | HConcatChart | VConcatChart | FacetChart | LayerChart" [override] def __add__(self, other: LayerChart | Chart) -> Self: ^~~~~~~~~~~~~~~~~~~~~~~~~ altair\vegalite\v5\api.py:4376: note: This violates the Liskov substitution principle altair\vegalite\v5\api.py:4376: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides ``` * chore(typing): Update more `dict` -> `dict[str, Any]` * style(ruff): fix whitespace * chore: Remove TODO fixed in #3480 * fix(typing): Enable `ANN003` and fix all in `api` * fix(typing): Enable `ANN002` and fix all in `api` * chore(ruff): Add note on `ANN` This could later be extended to other modules, but for now `api` is complete. * fix(typing): Add missing `FacetChart` annotations To align with the other `ChartType`s

Follow-up referenced in #3427 (comment)
Developing each function/method doc further with example(s)
Tasks
emptynote (adapted from docs: Addemptyas a explicitconditionkwarg #3490)Then.whenThen.otherwiseWhen.thenChainedWhen.thenalt.when(usingvega_datasets)__repr__forWhen,ChainedWhenTheninherits onePossible tasks
Just some ideas that came up while working on this.
Can work on them if there's interest, but not planning to otherwise:
emptynoteComments from original PR
Linking these as I raised them as potential issues, but they were not discussed:
Thenmethod autocomplete visibilityWhen | Then | ChainedWhen] method docs not in API referencepolarsbe referenced and/or accredited for idea?