Skip to content

Commit

Permalink
docs: Promote when-then-otherwise in User Guide (#3544)
Browse files Browse the repository at this point in the history
Co-authored-by: Dan Redding <125183946+dangotbanned@users.noreply.github.com>
Co-authored-by: Joel Ostblom <joel.ostblom@gmail.com>
Co-authored-by: Joel Ostblom <joelostblom@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 2, 2024
1 parent 211f7c5 commit 88c76e3
Show file tree
Hide file tree
Showing 64 changed files with 485 additions and 350 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ brush = alt.selection_interval()
points = alt.Chart(source).mark_point().encode(
x='Horsepower',
y='Miles_per_Gallon',
color=alt.condition(brush, 'Origin', alt.value('lightgray'))
color=alt.when(brush).then("Origin").otherwise(alt.value("lightgray"))
).add_params(
brush
)
Expand Down
29 changes: 20 additions & 9 deletions altair/vegalite/v5/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -913,14 +913,17 @@ def then(self, statement: _StatementType, /, **kwds: Any) -> Then[Any]:
A spec or value to use when the preceding :func:`.when()` clause is true.
.. note::
``str`` will be encoded as `shorthand<https://altair-viz.github.io/user_guide/encodings/index.html#encoding-shorthands>`__.
``str`` will be encoded as `shorthand`_.
**kwds
Additional keyword args are added to the resulting ``dict``.
Returns
-------
:class:`Then`
.. _shorthand:
https://altair-viz.github.io/user_guide/encodings/index.html#encoding-shorthands
Examples
--------
Simple conditions may be expressed without defining a default::
Expand Down Expand Up @@ -990,10 +993,12 @@ def otherwise(
Roughly equivalent to an ``else`` clause.
.. note::
``str`` will be encoded as `shorthand<https://altair-viz.github.io/user_guide/encodings/index.html#encoding-shorthands>`__.
``str`` will be encoded as `shorthand`_.
**kwds
Additional keyword args are added to the resulting ``dict``.
.. _shorthand:
https://altair-viz.github.io/user_guide/encodings/index.html#encoding-shorthands
Examples
--------
Expand Down Expand Up @@ -1071,14 +1076,16 @@ def when(
When ``predicate`` is a ``Parameter`` that is used more than once,
``alt.when().then().when(..., empty=...)`` provides granular control for each occurrence.
**constraints
Specify `Field Equal Predicate <https://vega.github.io/vega-lite/docs/predicate.html#equal-predicate>`__'s.
Specify `Field Equal Predicate`_'s.
Shortcut for ``alt.datum.field_name == value``, see examples for usage.
Returns
-------
:class:`ChainedWhen`
A partial state which requires calling :meth:`ChainedWhen.then()` to finish the condition.
.. _Field Equal Predicate:
https://vega.github.io/vega-lite/docs/predicate.html#equal-predicate
Examples
--------
Expand Down Expand Up @@ -1176,14 +1183,17 @@ def then(self, statement: _StatementType, /, **kwds: Any) -> Then[_Conditions]:
A spec or value to use when the preceding :meth:`Then.when()` clause is true.
.. note::
``str`` will be encoded as `shorthand<https://altair-viz.github.io/user_guide/encodings/index.html#encoding-shorthands>`__.
``str`` will be encoded as `shorthand`_.
**kwds
Additional keyword args are added to the resulting ``dict``.
Returns
-------
:class:`Then`
.. _shorthand:
https://altair-viz.github.io/user_guide/encodings/index.html#encoding-shorthands
Examples
--------
Multiple conditions with an implicit default::
Expand Down Expand Up @@ -1247,7 +1257,7 @@ def when(
When ``predicate`` is a ``Parameter`` that is used more than once,
``alt.when(..., empty=...)`` provides granular control for each occurrence.
**constraints
Specify `Field Equal Predicate <https://vega.github.io/vega-lite/docs/predicate.html#equal-predicate>`__'s.
Specify `Field Equal Predicate`_'s.
Shortcut for ``alt.datum.field_name == value``, see examples for usage.
Returns
Expand All @@ -1257,11 +1267,12 @@ def when(
Notes
-----
- Directly inspired by the ``when-then-otherwise`` syntax used in ``polars.when``.
- Directly inspired by the ``when-then-otherwise`` syntax used in `polars.when`_.
References
----------
`polars.when <https://docs.pola.rs/py-polars/html/reference/expressions/api/polars.when.html>`__
.. _Field Equal Predicate:
https://vega.github.io/vega-lite/docs/predicate.html#equal-predicate
.. _polars.when:
https://docs.pola.rs/py-polars/html/reference/expressions/api/polars.when.html
Examples
--------
Expand Down
31 changes: 14 additions & 17 deletions doc/case_studies/exploring-weather.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,31 +226,28 @@ of the selection (for more information on selections, see
.. altair-plot::

brush = alt.selection_interval()

points = alt.Chart().mark_point().encode(
alt.X('temp_max:Q').title('Maximum Daily Temperature (C)'),
alt.Y('temp_range:Q').title('Daily Temperature Range (C)'),
color=alt.condition(brush, 'weather:N', alt.value('lightgray'), scale=scale),
size=alt.Size('precipitation:Q').scale(range=[1, 200])
color = alt.Color("weather:N").scale(scale)
temp_range = alt.datum["temp_max"] - alt.datum["temp_min"]

points = alt.Chart(width=600, height=400).mark_point().encode(
alt.X("temp_max:Q").title("Maximum Daily Temperature (C)"),
alt.Y("temp_range:Q").title("Daily Temperature Range (C)"),
color=alt.when(brush).then(color).otherwise(alt.value("lightgray")),
size=alt.Size("precipitation:Q").scale(range=[1, 200]),
).transform_calculate(
"temp_range", "datum.temp_max - datum.temp_min"
).properties(
width=600,
height=400
temp_range=temp_range
).add_params(
brush
)

bars = alt.Chart().mark_bar().encode(
x='count()',
y='weather:N',
color=alt.Color('weather:N').scale(scale),
bars = alt.Chart(width=600).mark_bar().encode(
x="count()",
y="weather:N",
color=color
).transform_calculate(
"temp_range", "datum.temp_max - datum.temp_min"
temp_range=temp_range
).transform_filter(
brush
).properties(
width=600
)

alt.vconcat(points, bars, data=df)
Expand Down
15 changes: 6 additions & 9 deletions doc/user_guide/compound_charts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -364,28 +364,25 @@ layered chart with a hover selection:
.. altair-plot::

hover = alt.selection_point(on='pointerover', nearest=True, empty=False)
when_hover = alt.when(hover)

base = alt.Chart(iris).encode(
x='petalLength:Q',
y='petalWidth:Q',
color=alt.condition(hover, 'species:N', alt.value('lightgray'))
color=when_hover.then("species:N").otherwise(alt.value("lightgray"))
).properties(
width=180,
height=180,
)

points = base.mark_point().add_params(
hover
)
points = base.mark_point().add_params(hover)

text = base.mark_text(dy=-5).encode(
text = 'species:N',
opacity = alt.condition(hover, alt.value(1), alt.value(0))
text="species:N",
opacity=when_hover.then(alt.value(1)).otherwise(alt.value(0)),
)

alt.layer(points, text).facet(
'species:N',
)
(points + text).facet("species:N")

Though each of the above examples have faceted the data across columns,
faceting across rows (or across rows *and* columns) is supported as
Expand Down
40 changes: 12 additions & 28 deletions doc/user_guide/interactions/bindings_widgets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ where a drop-down is used to highlight cars of a specific ``Origin``:

input_dropdown = alt.binding_select(options=['Europe', 'Japan', 'USA'], name='Region ')
selection = alt.selection_point(fields=['Origin'], bind=input_dropdown)
color = alt.condition(
selection,
alt.Color('Origin:N').legend(None),
alt.value('lightgray')
color = (
alt.when(selection)
.then(alt.Color("Origin:N").legend(None))
.otherwise(alt.value("lightgray"))
)

alt.Chart(cars).mark_point().encode(
Expand All @@ -72,7 +72,7 @@ and selection parameters follow the same pattern as you will see further down
in the :ref:`encoding-channel-binding` section.

As you can see above,
we are still using ``conditions`` to make the chart respond to the selection,
we are still using :ref:`conditions <conditions>` to make the chart respond to the selection,
just as we did without widgets.
Bindings and input elements can also be used to filter data
allowing the user to see just the selected points as in the example below.
Expand Down Expand Up @@ -137,11 +137,7 @@ to see the point highlighted
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
tooltip='Name:N',
opacity=alt.condition(
search_input,
alt.value(1),
alt.value(0.05)
)
opacity=alt.when(search_input).then(alt.value(1)).otherwise(alt.value(0.05)),
).add_params(
search_input
)
Expand Down Expand Up @@ -185,16 +181,12 @@ which would have been the case if we just wrote ``xval < selector``.

slider = alt.binding_range(min=0, max=100, step=1, name='Cutoff ')
selector = alt.param(name='SelectorName', value=50, bind=slider)
predicate = alt.datum.xval < selector

alt.Chart(df).mark_point().encode(
x='xval',
y='yval',
color=alt.condition(
alt.datum.xval < selector,
# 'datum.xval < SelectorName', # An equivalent alternative
alt.value('red'),
alt.value('blue')
)
color=alt.when(predicate).then(alt.value("red")).otherwise(alt.value("blue")),
).add_params(
selector
)
Expand All @@ -213,16 +205,12 @@ points based on whether they are smaller or larger than the value:
bind=slider,
value=[{'cutoff': 50}]
)
predicate = alt.datum.xval < selector.cutoff

alt.Chart(df).mark_point().encode(
x='xval',
y='yval',
color=alt.condition(
alt.datum.xval < selector.cutoff,
# 'datum.xval < SelectorName.cutoff', # An equivalent alternative
alt.value('red'),
alt.value('blue')
)
color=alt.when(predicate).then(alt.value("red")).otherwise(alt.value("blue")),
).add_params(
selector
)
Expand Down Expand Up @@ -263,11 +251,7 @@ just if the value of the check box is True (checked) or False (unchecked):
alt.Chart(cars).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
size=alt.condition(
param_checkbox,
'Acceleration:Q',
alt.value(25)
)
size=alt.when(param_checkbox).then("Acceleration:Q").otherwise(alt.value(25)),
).add_params(
param_checkbox
)
Expand Down Expand Up @@ -315,7 +299,7 @@ Altair provides the ``bind='legend'`` option to facilitate the creation of click
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color='Origin:N',
opacity=alt.condition(selection, alt.value(0.8), alt.value(0.2))
opacity=alt.when(selection).then(alt.value(0.8)).otherwise(alt.value(0.2)),
).add_params(
selection
)
Expand Down
13 changes: 4 additions & 9 deletions doc/user_guide/interactions/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,14 @@ To try this out, you can type ``mazda|ford`` in the search input box below.
name='Search ',
)
)
search_matches = alt.expr.test(alt.expr.regexp(search_input, "i"), alt.datum.Name)

alt.Chart(cars).mark_point(size=60).encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
tooltip='Name:N',
opacity=alt.condition(
alt.expr.test(alt.expr.regexp(search_input, 'i'), alt.datum.Name),
# f"test(regexp({search_input.name}, 'i'), datum.Name)", # Equivalent js alternative
alt.value(1),
alt.value(0.05)
)
).add_params(
search_input
)
opacity=alt.when(search_matches).then(alt.value(1)).otherwise(alt.value(0.05)),
).add_params(search_input)

And remember, all this interactivity is client side.
You can save this chart as an HTML file or put it on a static site generator such as GitHub/GitLab pages
Expand Down
20 changes: 8 additions & 12 deletions doc/user_guide/interactions/jupyter_chart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,12 @@ is available as ``jchart.params.cutoff``.
slider = alt.binding_range(min=0, max=100, step=1)
cutoff = alt.param(name="cutoff", bind=slider, value=50)
predicate = alt.datum.xval < cutoff
chart = alt.Chart(df).mark_point().encode(
x='xval',
y='yval',
color=alt.condition(
alt.datum.xval < cutoff,
alt.value('red'), alt.value('blue')
)
color=alt.when(predicate).then(alt.value("red")).otherwise(alt.value("blue")),
).add_params(
cutoff
)
Expand Down Expand Up @@ -201,14 +199,12 @@ variable's value only from the ``IntSlider`` ipywidget.
})
cutoff = alt.param(name="cutoff", value=50)
predicate = alt.datum.xval < cutoff
chart = alt.Chart(df).mark_point().encode(
x='xval',
y='yval',
color=alt.condition(
alt.datum.xval < cutoff,
alt.value('red'), alt.value('blue')
)
color=alt.when(predicate).then(alt.value("red")).otherwise(alt.value("blue"))
).add_params(
cutoff
)
Expand Down Expand Up @@ -253,7 +249,7 @@ the legend.
chart = alt.Chart(source).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=alt.condition(brush, 'Origin:N', alt.value('grey')),
color=alt.when(brush).then("Origin:N").otherwise(alt.value("grey")),
).add_params(brush)
jchart = alt.JupyterChart(chart)
Expand Down Expand Up @@ -306,7 +302,7 @@ extract the selected rows in the input DataFrame.
chart = alt.Chart(source).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=alt.condition(brush, 'Origin:N', alt.value('grey')),
color=alt.when(brush).then("Origin:N").otherwise(alt.value("grey")),
).add_params(brush)
jchart = alt.JupyterChart(chart)
Expand Down Expand Up @@ -344,7 +340,7 @@ is a dictionary from column names to selection intervals
chart = alt.Chart(source).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=alt.condition(brush, 'Cylinders:O', alt.value('grey')),
color=alt.when(brush).then("Cylinders:O").otherwise(alt.value("grey")),
).add_params(brush)
jchart = alt.JupyterChart(chart)
Expand Down Expand Up @@ -399,7 +395,7 @@ is used to combine the chart and HTML table in a column layout.
chart_widget = alt.JupyterChart(alt.Chart(source).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=alt.condition(brush, 'Cylinders:O', alt.value('grey')),
color=alt.when(brush).then("Cylinders:O").otherwise(alt.value("grey")),
).add_params(brush))
table_widget = HTML(value=source.iloc[:0].to_html())
Expand Down
Loading

0 comments on commit 88c76e3

Please sign in to comment.