diff --git a/README.md b/README.md index 0e14e8826..6134975c6 100644 --- a/README.md +++ b/README.md @@ -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 ) diff --git a/altair/vegalite/v5/api.py b/altair/vegalite/v5/api.py index a3070acbf..51d3f2cac 100644 --- a/altair/vegalite/v5/api.py +++ b/altair/vegalite/v5/api.py @@ -913,7 +913,7 @@ 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`__. + ``str`` will be encoded as `shorthand`_. **kwds Additional keyword args are added to the resulting ``dict``. @@ -921,6 +921,9 @@ def then(self, statement: _StatementType, /, **kwds: Any) -> Then[Any]: ------- :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:: @@ -990,10 +993,12 @@ def otherwise( Roughly equivalent to an ``else`` clause. .. note:: - ``str`` will be encoded as `shorthand`__. + ``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 -------- @@ -1071,7 +1076,7 @@ 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 `__'s. + Specify `Field Equal Predicate`_'s. Shortcut for ``alt.datum.field_name == value``, see examples for usage. Returns @@ -1079,6 +1084,8 @@ def when( :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 -------- @@ -1176,7 +1183,7 @@ 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`__. + ``str`` will be encoded as `shorthand`_. **kwds Additional keyword args are added to the resulting ``dict``. @@ -1184,6 +1191,9 @@ def then(self, statement: _StatementType, /, **kwds: Any) -> Then[_Conditions]: ------- :class:`Then` + .. _shorthand: + https://altair-viz.github.io/user_guide/encodings/index.html#encoding-shorthands + Examples -------- Multiple conditions with an implicit default:: @@ -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 `__'s. + Specify `Field Equal Predicate`_'s. Shortcut for ``alt.datum.field_name == value``, see examples for usage. Returns @@ -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 `__ + .. _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 -------- diff --git a/doc/case_studies/exploring-weather.rst b/doc/case_studies/exploring-weather.rst index bc9776787..ad2a3bc2d 100644 --- a/doc/case_studies/exploring-weather.rst +++ b/doc/case_studies/exploring-weather.rst @@ -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) diff --git a/doc/user_guide/compound_charts.rst b/doc/user_guide/compound_charts.rst index 503add798..a39114d38 100644 --- a/doc/user_guide/compound_charts.rst +++ b/doc/user_guide/compound_charts.rst @@ -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 diff --git a/doc/user_guide/interactions/bindings_widgets.rst b/doc/user_guide/interactions/bindings_widgets.rst index dc62a6e11..9a62307dc 100644 --- a/doc/user_guide/interactions/bindings_widgets.rst +++ b/doc/user_guide/interactions/bindings_widgets.rst @@ -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( @@ -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 ` 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. @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) diff --git a/doc/user_guide/interactions/expressions.rst b/doc/user_guide/interactions/expressions.rst index a73751ef4..a4e9440ab 100644 --- a/doc/user_guide/interactions/expressions.rst +++ b/doc/user_guide/interactions/expressions.rst @@ -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 diff --git a/doc/user_guide/interactions/jupyter_chart.rst b/doc/user_guide/interactions/jupyter_chart.rst index 88982c06b..a4ad028d1 100644 --- a/doc/user_guide/interactions/jupyter_chart.rst +++ b/doc/user_guide/interactions/jupyter_chart.rst @@ -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 ) @@ -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 ) @@ -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) @@ -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) @@ -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) @@ -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()) diff --git a/doc/user_guide/interactions/parameters.rst b/doc/user_guide/interactions/parameters.rst index 1dce8c116..cf42d572b 100644 --- a/doc/user_guide/interactions/parameters.rst +++ b/doc/user_guide/interactions/parameters.rst @@ -3,7 +3,10 @@ .. _parameters: Parameters, Conditions, & Filters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +================================= + +Parameters +~~~~~~~~~~ Parameters are the building blocks of interaction in Altair. There are two types of parameters: *variables* and *selections*. We introduce these concepts through a series of examples. @@ -146,25 +149,29 @@ we created a selection parameter using ``brush = alt.selection_interval()``, and we attached that parameter to the chart using ``add_params``. One difference is that here we have not defined how the chart should respond to the selection; you will learn this in the next section. -Conditions & Filters -~~~~~~~~~~~~~~~~~~~~ +.. _conditions: -Conditional Encodings -^^^^^^^^^^^^^^^^^^^^^ +Conditions +~~~~~~~~~~ + +.. note:: + + This material was changed considerably with the release of Altair ``5.5.0``. + :func:`when` was introduced in ``5.4.0`` and should be preferred over :func:`condition`. The example above is neat, but the selection interval doesn't actually *do* anything yet. -To make the chart respond to this selection, we need to reference the selection in within -the chart specification. Here, we will use the :func:`condition` function to create -a conditional color encoding: we'll tie the color to the ``"Origin"`` -column for points in the selection, and set the color to ``"lightgray"`` -for points outside the selection: +To make the chart respond to this selection, we need to reference ``brush`` within +the chart specification. Here, we will use the :func:`when` function to create +a conditional color encoding: .. altair-plot:: + conditional = alt.when(brush).then("Origin:N").otherwise(alt.value("lightgray")) + alt.Chart(cars).mark_point().encode( - x='Horsepower:Q', - y='Miles_per_Gallon:Q', - color=alt.condition(brush, 'Origin:N', alt.value('lightgray')) + x="Horsepower:Q", + y="Miles_per_Gallon:Q", + color=conditional, ).add_params( brush ) @@ -172,16 +179,68 @@ for points outside the selection: As you can see, the color of the points now changes depending on whether they are inside or outside the selection. Above we are using the selection parameter ``brush`` as a *predicate* (something that evaluates as `True` or `False`). -This is controlled by the line ``color=alt.condition(brush, 'Origin:N', alt.value('lightgray'))``. + +This is controlled by our definition ``conditional``:: + + conditional = alt.when(brush).then("Origin:N").otherwise(alt.value("lightgray")) + Data points which fall within the selection evaluate as ``True``, and data points which fall outside the selection evaluate to ``False``. -The ``'Origin:N'`` specifies how to color the points which fall within the selection, -and the ``alt.value('lightgray')`` specifies that the outside points should be given a constant color value; -you can remember this as ``alt.condition(, , )``. +The ``"Origin:N"`` specifies how to color the points which fall within the selection, +and the ``alt.value('lightgray')`` specifies that the outside points should be given a constant color value. + +Understanding :func:`when` +^^^^^^^^^^^^^^^^^^^^^^^^^^ -This approach becomes even more powerful when the selection behavior is +The ``when-then-otherwise`` syntax was directly inspired by `polars.when`_, +and is similar to an ``if-else`` statement written in Python:: + + # alt.when(brush) + if brush: + # .then("Origin:N") + color = "Origin:N" + else: + # .otherwise(alt.value("lightgray")) + color = alt.value("lightgray") + +Omitting the ``.otherwise()`` clause will use the channel default instead: + +.. altair-plot:: + + source = data.cars() + brush = alt.selection_interval() + + points = alt.Chart(source).mark_point().encode( + x="Horsepower", + y="Miles_per_Gallon", + color=alt.when(brush).then(alt.value("goldenrod")) + ).add_params( + brush + ) + + points + +Multiple conditional branches (``if, elif, ..., elif`` in Python) +are expressed via chained calls to :func:`when`. +You will see an example with working code in :ref:`conditional-branches` +when you have learned about different selection types. + +More advanced use of conditions can be found +in the :func:`when` API reference +and in these gallery examples: + +- :ref:`gallery_dot_dash_plot` +- :ref:`gallery_interactive_bar_select_highlight` +- :ref:`gallery_multiline_tooltip_standard` +- :ref:`gallery_scatter_point_paths_hover` +- :ref:`gallery_waterfall_chart` + +Linking Conditions Across Charts +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Conditional encodings become even more powerful when the selection behavior is tied across multiple views of the data within a compound chart. -For example, here we create a ``chart`` object using the same code as +For example, here we create a :class:`Chart` using the same code as above, and horizontally concatenate two versions of this chart: one with the x-encoding tied to ``"Horsepower"``, and one with the x-encoding tied to ``"Acceleration"`` @@ -191,7 +250,7 @@ tied to ``"Acceleration"`` chart = alt.Chart(cars).mark_point().encode( x='Horsepower:Q', y='Miles_per_Gallon:Q', - color=alt.condition(brush, 'Origin:N', alt.value('lightgray')) + color=alt.when(brush).then("Origin:N").otherwise(alt.value("lightgray")), ).properties( width=250, height=250 @@ -218,7 +277,7 @@ We can modify the brush definition, and leave the rest of the code unchanged: chart = alt.Chart(cars).mark_point().encode( x='Horsepower:Q', y='Miles_per_Gallon:Q', - color=alt.condition(brush, 'Origin:N', alt.value('lightgray')) + color=alt.when(brush).then("Origin:N").otherwise(alt.value("lightgray")), ).properties( width=250, height=250 @@ -231,15 +290,18 @@ We can modify the brush definition, and leave the rest of the code unchanged: As you might have noticed, the selected points are sometimes obscured by some of the unselected points. To bring the selected points to the foreground, -we can change the order in which they are laid out via the following -encoding: ``order=alt.condition(hover, alt.value(1), alt.value(0))``. -You can see an example of this in the :ref:`gallery_selection_zorder` gallery example. +we can change the order in which they are laid out via the following encoding:: -Filtering Data -^^^^^^^^^^^^^^ + hover = alt.selection_point(on='pointerover', nearest=True, empty=False) + order = alt.when(hover).then(alt.value(1)).otherwise(alt.value(0)) + + + +Filters +~~~~~~~ Using a selection parameter to filter data works in much the same way -as using it within ``condition``. +as using it within :func:`when`. For example, in ``transform_filter(brush)``, we are again using the selection parameter ``brush`` as a predicate. Data points which evaluate to ``True`` (i.e., data points which lie within the selection) are kept, @@ -296,7 +358,7 @@ selection: return alt.Chart(cars).mark_rect().encode( x="Cylinders:O", y="Origin:N", - color=alt.condition(selector, 'count()', alt.value('lightgray')) + color=alt.when(selector).then("count()").otherwise(alt.value("lightgray")), ).properties( width=300, height=180 @@ -328,6 +390,16 @@ empty selection contains none of the points: interval_x = alt.selection_interval(encodings=['x'], empty=False) make_example(interval_x) +The ``empty=False`` argument could instead be set inside :func:`when`, +to change the behavior of each condition when an empty selection is passed, +rather than having to define separate selection objects:: + + brush = alt.selection_interval() + ... + color=alt.when(brush).then(...) + size=alt.when(brush, empty=False).then(...) + ... + Point Selections ^^^^^^^^^^^^^^^^ A *point* selection allows you to select chart elements one at a time @@ -367,10 +439,10 @@ with a matching ``Origin``. .. altair-plot:: selection = alt.selection_point(fields=['Origin']) - 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")) ) scatter = alt.Chart(cars).mark_point().encode( @@ -402,10 +474,10 @@ cylinders: .. altair-plot:: selection = alt.selection_point(fields=['Origin', 'Cylinders']) - 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")) ) scatter = alt.Chart(cars).mark_point().encode( @@ -428,9 +500,85 @@ cylinders: By fine-tuning the behavior of selections in this way, they can be used to create a wide variety of linked interactive chart types. +Combining Parameters +~~~~~~~~~~~~~~~~~~~~ + +Multiple parameters can be combined in a single chart, +either via multiple separate response conditions, +different conditional branches in :func:`when`, +or parameter composition. + +Multiple conditions +^^^^^^^^^^^^^^^^^^^ + +In this example, +points that are hovered with the pointer +will increase in size +and those that are clicked +will be filled in with red. +The ``empty=False`` is to ensure that no points are selected to start. +Try holding shift to select multiple points on either hover or click. + +.. altair-plot:: + + click = alt.selection_point(empty=False) + hover = alt.selection_point(on='pointerover', empty=False) + + points = alt.Chart(cars).mark_point().encode( + x='Horsepower:Q', + y='Miles_per_Gallon:Q', + fill=alt.when(click).then(alt.value('red')), + size=alt.when(hover).then(alt.value(1000)) + ).add_params( + click, hover + ) + + points + +.. _conditional-branches: + +Conditional branches +^^^^^^^^^^^^^^^^^^^^ + +:func:`when` allows the use of multiple ``then`` (``elif``) branches +which can change the behavior of a single encoding +in response to multiple different parameters. +Here, +we fill hovered points in yellow, +before changing the fill to red +when a point is clicked. +Since the mouse is hovering over points +while clicking them, +both conditions will be active +and the earlier branch takes precedence +(you can try by changing the order of the two ``when.then`` clauses +and observing that the points will not change to red when clicked). + +.. altair-plot:: + + click = alt.selection_point(empty=False) + hover = alt.selection_point(on='pointerover', empty=False) + + points = alt.Chart(cars).mark_point().encode( + x='Horsepower:Q', + y='Miles_per_Gallon:Q', + fill=( + alt.when(click) + .then(alt.value('red')) + .when(hover) + .then(alt.value('gold')) + ), + size=alt.when(hover).then(alt.value(1000)) + ).add_params( + click, hover + ) + + points + +.. _parameter-composition: Parameter Composition -~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^ Altair also supports combining multiple parameters using the ``&``, ``|`` and ``~`` for respectively ``AND``, ``OR`` and ``NOT`` logical composition @@ -462,7 +610,7 @@ selection alt.Chart(cars).mark_rect().encode( x='Cylinders:O', y='Origin:O', - color=alt.condition(alex | morgan, 'count()', alt.ColorValue("grey")) + color=alt.when(alex | morgan).then("count()").otherwise(alt.value("grey")), ).add_params( alex, morgan ).properties( @@ -482,3 +630,5 @@ For more information on how to fine-tune selections, including specifying other mouse and keystroke options, see the `Vega-Lite Selection documentation `_. +.. _polars.when: + https://docs.pola.rs/py-polars/html/reference/expressions/api/polars.when.html diff --git a/doc/user_guide/marks/geoshape.rst b/doc/user_guide/marks/geoshape.rst index 4db48f98c..4c612ca61 100644 --- a/doc/user_guide/marks/geoshape.rst +++ b/doc/user_guide/marks/geoshape.rst @@ -529,9 +529,10 @@ populous states. Using an ``alt.selection_point()`` we define a selection parame # define a pointer selection click_state = alt.selection_point(fields=["state"]) + # define a condition on the opacity encoding depending on the selection + opacity = alt.when(click_state).then(alt.value(1)).otherwise(alt.value(0.2)) # create a choropleth map using a lookup transform - # define a condition on the opacity encoding depending on the selection choropleth = ( alt.Chart(us_states) .mark_geoshape() @@ -540,13 +541,13 @@ populous states. Using an ``alt.selection_point()`` we define a selection parame ) .encode( color="population:Q", - opacity=alt.condition(click_state, alt.value(1), alt.value(0.2)), + opacity=opacity, tooltip=["state:N", "population:Q"], ) .project(type="albersUsa") ) - # create a bar chart with a similar condition on the opacity encoding. + # create a bar chart with the same conditional ``opacity`` encoding. bars = ( alt.Chart( us_population.nlargest(15, "population"), title="Top 15 states by population" @@ -554,7 +555,7 @@ populous states. Using an ``alt.selection_point()`` we define a selection parame .mark_bar() .encode( x="population", - opacity=alt.condition(click_state, alt.value(1), alt.value(0.2)), + opacity=opacity, color="population", y=alt.Y("state").sort("-x"), ) @@ -616,7 +617,7 @@ We use here an elegant way to access the nested point coordinates from the geome .encode( longitude="lon:Q", latitude="lat:Q", - strokeWidth=alt.condition(hover, alt.value(1, empty=False), alt.value(0)), + strokeWidth=alt.when(hover, empty=False).then(alt.value(1)).otherwise(alt.value(0)), size=alt.Size( "mag:Q", scale=alt.Scale(type="pow", range=[1, 1000], domain=[0, 6], exponent=4), diff --git a/doc/user_guide/marks/line.rst b/doc/user_guide/marks/line.rst index 13f638f25..feda5bbf5 100644 --- a/doc/user_guide/marks/line.rst +++ b/doc/user_guide/marks/line.rst @@ -139,7 +139,7 @@ We can further apply selection to highlight a certain line on hover. ) lines = base.mark_line().encode( - size=alt.condition(~highlight, alt.value(1), alt.value(3)) + size=alt.when(~highlight).then(alt.value(1)).otherwise(alt.value(3)) ) points + lines diff --git a/doc/user_guide/marks/text.rst b/doc/user_guide/marks/text.rst index 4bae2f8b5..35d363fce 100644 --- a/doc/user_guide/marks/text.rst +++ b/doc/user_guide/marks/text.rst @@ -127,13 +127,10 @@ Text Table Heatmap .legend(direction="horizontal") ) + predicate = alt.datum.num_cars > 100 text = base.mark_text(baseline="middle").encode( text="num_cars:Q", - color=alt.condition( - alt.datum.num_cars > 100, - alt.value("black"), - alt.value("white"), - ), + color=alt.when(predicate).then(alt.value("black")).otherwise(alt.value("white")), ) heatmap + text diff --git a/doc/user_guide/times_and_dates.rst b/doc/user_guide/times_and_dates.rst index a8cd47ab3..98ad9390c 100644 --- a/doc/user_guide/times_and_dates.rst +++ b/doc/user_guide/times_and_dates.rst @@ -187,12 +187,13 @@ way that Altair expects: df = pd.DataFrame({'local': ['2018-01-01T00:00:00'], 'utc': ['2018-01-01T00:00:00Z']}) + when_compliant = alt.when(compliant=True) alt.Chart(df).transform_calculate( compliant="hours(datum.local) != hours(datum.utc) ? true : false", - ).mark_text(size=20, baseline='middle').encode( - text=alt.condition('datum.compliant', alt.value('OK'), alt.value('not OK')), - color=alt.condition('datum.compliant', alt.value('green'), alt.value('red')) + ).mark_text(size=20, baseline="middle").encode( + text=when_compliant.then(alt.value("OK")).otherwise(alt.value("not OK")), + color=when_compliant.then(alt.value("green")).otherwise(alt.value("red")), ).properties(width=80, height=50) If the above output contains a red "not OK": diff --git a/doc/user_guide/transform/filter.rst b/doc/user_guide/transform/filter.rst index 3fca3f196..fb4c7420f 100644 --- a/doc/user_guide/transform/filter.rst +++ b/doc/user_guide/transform/filter.rst @@ -135,30 +135,24 @@ to select the data to be shown in the top chart: selection = alt.selection_point(fields=['year']) - top = alt.Chart().mark_line().encode( - x='age:O', - y='sum(people):Q', - color='year:O' - ).properties( - width=600, height=200 + top = alt.Chart(width=600, height=200).mark_line().encode( + x="age:O", + y="sum(people):Q", + color="year:O" ).transform_filter( selection ) - bottom = alt.Chart().mark_bar().encode( - x='year:O', - y='sum(people):Q', - color=alt.condition(selection, alt.value('steelblue'), alt.value('lightgray')) - ).properties( - width=600, height=100 + color = alt.when(selection).then(alt.value("steelblue")).otherwise(alt.value("lightgray")) + bottom = alt.Chart(width=600, height=100).mark_bar().encode( + x="year:O", + y="sum(people):Q", + color=color ).add_params( selection ) - alt.vconcat( - top, bottom, - data=pop - ) + alt.vconcat(top, bottom, data=pop) Logical Operands ^^^^^^^^^^^^^^^^ diff --git a/doc/user_guide/transform/pivot.rst b/doc/user_guide/transform/pivot.rst index eb3746c73..eb280d1e5 100644 --- a/doc/user_guide/transform/pivot.rst +++ b/doc/user_guide/transform/pivot.rst @@ -43,27 +43,27 @@ values on multiple lines: .. altair-plot:: - import altair as alt - from vega_datasets import data + import altair as alt + from vega_datasets import data - source = data.stocks() - base = alt.Chart(source).encode(x='date:T') - columns = sorted(source.symbol.unique()) - selection = alt.selection_point( - fields=['date'], nearest=True, on='pointerover', empty=False, clear='pointerout' - ) + source = data.stocks() + base = alt.Chart(source).encode(x='date:T') + columns = sorted(source.symbol.unique()) + selection = alt.selection_point( + fields=['date'], nearest=True, on='pointerover', empty=False, clear='pointerout' + ) - lines = base.mark_line().encode(y='price:Q', color='symbol:N') - points = lines.mark_point().transform_filter(selection) + lines = base.mark_line().encode(y='price:Q', color='symbol:N') + points = lines.mark_point().transform_filter(selection) rule = base.transform_pivot( 'symbol', value='price', groupby=['date'] ).mark_rule().encode( - opacity=alt.condition(selection, alt.value(0.3), alt.value(0)), + opacity=alt.when(selection).then(alt.value(0.3)).otherwise(alt.value(0)), tooltip=[alt.Tooltip(c, type='quantitative') for c in columns] ).add_params(selection) - lines + points + rule + lines + points + rule Transform Options diff --git a/tests/examples_arguments_syntax/bar_chart_with_highlighted_bar.py b/tests/examples_arguments_syntax/bar_chart_with_highlighted_bar.py index d277bf9f3..1041fb99f 100644 --- a/tests/examples_arguments_syntax/bar_chart_with_highlighted_bar.py +++ b/tests/examples_arguments_syntax/bar_chart_with_highlighted_bar.py @@ -9,13 +9,13 @@ source = data.wheat() +# If the `year` column equals `1810` +# then, set the bar color to `"orange"` +# otherwise, use `"steelblue"` +color = alt.when(year=1810).then(alt.value("orange")).otherwise(alt.value("steelblue")) + alt.Chart(source).mark_bar().encode( - x='year:O', + x="year:O", y="wheat:Q", - # The highlight will be set on the result of a conditional statement - color=alt.condition( - alt.datum.year == 1810, # If the year is 1810 this test returns True, - alt.value('orange'), # which sets the bar orange. - alt.value('steelblue') # And if it's not true it sets the bar steelblue. - ) + color=color ).properties(width=600) diff --git a/tests/examples_arguments_syntax/bar_chart_with_negatives.py b/tests/examples_arguments_syntax/bar_chart_with_negatives.py index 127a16ba4..d3ff3fbc5 100644 --- a/tests/examples_arguments_syntax/bar_chart_with_negatives.py +++ b/tests/examples_arguments_syntax/bar_chart_with_negatives.py @@ -9,12 +9,11 @@ source = data.us_employment() +predicate = alt.datum.nonfarm_change > 0 +color = alt.when(predicate).then(alt.value("steelblue")).otherwise(alt.value("orange")) + alt.Chart(source).mark_bar().encode( x="month:T", y="nonfarm_change:Q", - color=alt.condition( - alt.datum.nonfarm_change > 0, - alt.value("steelblue"), # The positive color - alt.value("orange") # The negative color - ) + color=color ).properties(width=600) diff --git a/tests/examples_arguments_syntax/candlestick_chart.py b/tests/examples_arguments_syntax/candlestick_chart.py index 23b338b8e..4dc524782 100644 --- a/tests/examples_arguments_syntax/candlestick_chart.py +++ b/tests/examples_arguments_syntax/candlestick_chart.py @@ -12,9 +12,11 @@ source = data.ohlc() -open_close_color = alt.condition("datum.open <= datum.close", - alt.value("#06982d"), - alt.value("#ae1325")) +open_close_color = ( + alt.when("datum.open <= datum.close") + .then(alt.value("#06982d")) + .otherwise(alt.value("#ae1325")) +) base = alt.Chart(source).encode( alt.X('date:T', diff --git a/tests/examples_arguments_syntax/dot_dash_plot.py b/tests/examples_arguments_syntax/dot_dash_plot.py index 72d73d2e8..64c6ef450 100644 --- a/tests/examples_arguments_syntax/dot_dash_plot.py +++ b/tests/examples_arguments_syntax/dot_dash_plot.py @@ -12,28 +12,30 @@ # Configure the options common to all layers brush = alt.selection_interval() +brush_origin = alt.when(brush).then("Origin") base = alt.Chart(source).add_params(brush) # Configure the points points = base.mark_point().encode( x=alt.X('Miles_per_Gallon', title=''), y=alt.Y('Horsepower', title=''), - color=alt.condition(brush, 'Origin', alt.value('grey')) + color=brush_origin.otherwise(alt.value("grey")), ) # Configure the ticks tick_axis = alt.Axis(labels=False, domain=False, ticks=False) +tick_color = brush_origin.otherwise(alt.value("lightgrey")) x_ticks = base.mark_tick().encode( alt.X('Miles_per_Gallon', axis=tick_axis), alt.Y('Origin', title='', axis=tick_axis), - color=alt.condition(brush, 'Origin', alt.value('lightgrey')) + color=tick_color ) y_ticks = base.mark_tick().encode( alt.X('Origin', title='', axis=tick_axis), alt.Y('Horsepower', axis=tick_axis), - color=alt.condition(brush, 'Origin', alt.value('lightgrey')) + color=tick_color ) # Build the chart diff --git a/tests/examples_arguments_syntax/interactive_brush.py b/tests/examples_arguments_syntax/interactive_brush.py index 2cfd66037..bee087c57 100644 --- a/tests/examples_arguments_syntax/interactive_brush.py +++ b/tests/examples_arguments_syntax/interactive_brush.py @@ -15,5 +15,5 @@ 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) diff --git a/tests/examples_arguments_syntax/interactive_column_selection.py b/tests/examples_arguments_syntax/interactive_column_selection.py index 1c82aad8f..0fa4826aa 100644 --- a/tests/examples_arguments_syntax/interactive_column_selection.py +++ b/tests/examples_arguments_syntax/interactive_column_selection.py @@ -37,7 +37,7 @@ alt.X('level_0', title=None), alt.Y('level_1', title=None), alt.Color('correlation', scale=alt.Scale(domain=[-1, 1], scheme='blueorange')), - opacity=alt.condition(select_x & select_y, alt.value(1), alt.value(0.4)) + opacity=alt.when(select_x, select_y).then(alt.value(1)).otherwise(alt.value(0.4)), ).add_params( select_x, select_y ) diff --git a/tests/examples_arguments_syntax/interactive_cross_highlight.py b/tests/examples_arguments_syntax/interactive_cross_highlight.py index 796dc3110..f2b7e2d2a 100644 --- a/tests/examples_arguments_syntax/interactive_cross_highlight.py +++ b/tests/examples_arguments_syntax/interactive_cross_highlight.py @@ -34,7 +34,7 @@ bar = alt.Chart(source).mark_bar().encode( x='Major_Genre:N', y='count()', - color=alt.condition(pts, alt.ColorValue("steelblue"), alt.ColorValue("grey")) + color=alt.when(pts).then(alt.ColorValue("steelblue")).otherwise(alt.ColorValue("grey")) ).properties( width=550, height=200 diff --git a/tests/examples_arguments_syntax/interactive_legend.py b/tests/examples_arguments_syntax/interactive_legend.py index bd8b14b1a..61e45f44d 100644 --- a/tests/examples_arguments_syntax/interactive_legend.py +++ b/tests/examples_arguments_syntax/interactive_legend.py @@ -17,7 +17,7 @@ alt.X('yearmonth(date):T', axis=alt.Axis(domain=False, format='%Y', tickSize=0)), alt.Y('sum(count):Q', stack='center', axis=None), alt.Color('series:N', scale=alt.Scale(scheme='category20b')), - opacity=alt.condition(selection, alt.value(1), alt.value(0.2)) + opacity=alt.when(selection).then(alt.value(1)).otherwise(alt.value(0.2)) ).add_params( selection ) diff --git a/tests/examples_arguments_syntax/interactive_reorder_stacked_bars.py b/tests/examples_arguments_syntax/interactive_reorder_stacked_bars.py index 606bc37a1..2fbed1dca 100644 --- a/tests/examples_arguments_syntax/interactive_reorder_stacked_bars.py +++ b/tests/examples_arguments_syntax/interactive_reorder_stacked_bars.py @@ -25,7 +25,7 @@ y='variety:N', color='site:N', order='site_order:N', - opacity=alt.condition(selection, alt.value(0.9), alt.value(0.2)) + opacity=alt.when(selection).then(alt.value(0.9)).otherwise(alt.value(0.2)) ).add_params( selection ) diff --git a/tests/examples_arguments_syntax/interval_selection_map_quakes.py b/tests/examples_arguments_syntax/interval_selection_map_quakes.py index 6ab6bed8d..3a2d71c86 100644 --- a/tests/examples_arguments_syntax/interval_selection_map_quakes.py +++ b/tests/examples_arguments_syntax/interval_selection_map_quakes.py @@ -38,7 +38,7 @@ ).mark_circle(opacity=0.35, tooltip=True).encode( longitude="lon:Q", latitude="lat:Q", - color=alt.condition(brush, alt.value("goldenrod"), alt.value("steelblue")), + color=alt.when(brush).then(alt.value("goldenrod")).otherwise(alt.value("steelblue")), size=alt.Size("mag:Q", scale=alt.Scale(type="pow", range=[1, 1000], domain=[0, 7], exponent=4)), ).add_params(brush) diff --git a/tests/examples_arguments_syntax/lasagna_plot.py b/tests/examples_arguments_syntax/lasagna_plot.py index 6f603b8e1..d3e60ed34 100644 --- a/tests/examples_arguments_syntax/lasagna_plot.py +++ b/tests/examples_arguments_syntax/lasagna_plot.py @@ -8,10 +8,10 @@ source = data.stocks() -color_condition = alt.condition( - "month(datum.value) == 1 && date(datum.value) == 1", - alt.value("black"), - alt.value(None), +color_condition = ( + alt.when(alt.expr.month("datum.value") == 1, alt.expr.date("datum.value") == 1) + .then(alt.value("black")) + .otherwise(alt.value(None)) ) alt.Chart(source, width=300, height=100).transform_filter( diff --git a/tests/examples_arguments_syntax/layered_heatmap_text.py b/tests/examples_arguments_syntax/layered_heatmap_text.py index dc912ed8b..7dec0fd26 100644 --- a/tests/examples_arguments_syntax/layered_heatmap_text.py +++ b/tests/examples_arguments_syntax/layered_heatmap_text.py @@ -28,14 +28,14 @@ ) ) +color = ( + alt.when(alt.datum.mean_horsepower > 150) + .then(alt.value("black")) + .otherwise(alt.value("white")) +) # Configure text text = base.mark_text(baseline='middle').encode( - text=alt.Text('mean_horsepower:Q', format=".0f"), - color=alt.condition( - alt.datum.mean_horsepower > 150, - alt.value('black'), - alt.value('white') - ) + text=alt.Text('mean_horsepower:Q', format=".0f"), color=color ) # Draw the chart diff --git a/tests/examples_arguments_syntax/multiline_highlight.py b/tests/examples_arguments_syntax/multiline_highlight.py index 5da841516..575c88081 100644 --- a/tests/examples_arguments_syntax/multiline_highlight.py +++ b/tests/examples_arguments_syntax/multiline_highlight.py @@ -30,7 +30,7 @@ ) lines = base.mark_line().encode( - size=alt.condition(~highlight, alt.value(1), alt.value(3)) + size=alt.when(~highlight).then(alt.value(1)).otherwise(alt.value(3)) ) points + lines diff --git a/tests/examples_arguments_syntax/multiline_tooltip.py b/tests/examples_arguments_syntax/multiline_tooltip.py index 12ac92bf0..d2bd7ff8f 100644 --- a/tests/examples_arguments_syntax/multiline_tooltip.py +++ b/tests/examples_arguments_syntax/multiline_tooltip.py @@ -41,15 +41,16 @@ ).add_params( nearest ) +when_near = alt.when(nearest) # Draw points on the line, and highlight based on selection points = line.mark_point().encode( - opacity=alt.condition(nearest, alt.value(1), alt.value(0)) + opacity=when_near.then(alt.value(1)).otherwise(alt.value(0)) ) # Draw text labels near the points, and highlight based on selection text = line.mark_text(align="left", dx=5, dy=-5).encode( - text=alt.condition(nearest, "y:Q", alt.value(" ")) + text=when_near.then("y:Q").otherwise(alt.value(" ")) ) # Draw a rule at the location of the selection diff --git a/tests/examples_arguments_syntax/multiline_tooltip_standard.py b/tests/examples_arguments_syntax/multiline_tooltip_standard.py index 990aa2015..bbab79d46 100644 --- a/tests/examples_arguments_syntax/multiline_tooltip_standard.py +++ b/tests/examples_arguments_syntax/multiline_tooltip_standard.py @@ -28,10 +28,11 @@ y="y:Q", color="category:N" ) +when_near = alt.when(nearest) # Draw points on the line, and highlight based on selection points = line.mark_point().encode( - opacity=alt.condition(nearest, alt.value(1), alt.value(0)) + opacity=when_near.then(alt.value(1)).otherwise(alt.value(0)) ) # Draw a rule at the location of the selection @@ -41,7 +42,7 @@ groupby=["x"] ).mark_rule(color="gray").encode( x="x:Q", - opacity=alt.condition(nearest, alt.value(0.3), alt.value(0)), + opacity=when_near.then(alt.value(0.3)).otherwise(alt.value(0)), tooltip=[alt.Tooltip(c, type="quantitative") for c in columns], ).add_params(nearest) diff --git a/tests/examples_arguments_syntax/multiple_interactions.py b/tests/examples_arguments_syntax/multiple_interactions.py index 8fbc4281e..96bfb8fed 100644 --- a/tests/examples_arguments_syntax/multiple_interactions.py +++ b/tests/examples_arguments_syntax/multiple_interactions.py @@ -61,32 +61,32 @@ rating_radio = alt.binding_radio(options=ratings, name="Rating") rating_select = alt.selection_point(fields=['MPAA_Rating'], bind=rating_radio) -rating_color_condition = alt.condition( - rating_select, - alt.Color('MPAA_Rating:N', legend=None), - alt.value('lightgray') +rating_color = ( + alt.when(rating_select) + .then(alt.Color('MPAA_Rating:N', legend=None)) + .otherwise(alt.value("lightgray")) ) highlight_ratings = base.add_params( rating_select ).encode( - color=rating_color_condition + color=rating_color ).properties(title="Radio Button Highlighting") # Boolean selection for format changes input_checkbox = alt.binding_checkbox(name="Big Budget Films ") checkbox_selection = alt.param(bind=input_checkbox) -size_checkbox_condition = alt.condition( - checkbox_selection, - alt.Size('Hundred_Million_Production:Q'), - alt.SizeValue(25) +size_checkbox = ( + alt.when(checkbox_selection) + .then(alt.Size('Big_Budget_Film:N', scale=alt.Scale(range=[25, 150]))) + .otherwise(alt.value(25)) ) budget_sizing = base.add_params( checkbox_selection ).encode( - size=size_checkbox_condition + size=size_checkbox ).properties(title="Checkbox Formatting") -(filter_year | filter_genres) & (highlight_ratings | budget_sizing) +(filter_year | budget_sizing) & (highlight_ratings | filter_genres) diff --git a/tests/examples_arguments_syntax/scatter_linked_brush.py b/tests/examples_arguments_syntax/scatter_linked_brush.py index adf88d34b..b8548fd02 100644 --- a/tests/examples_arguments_syntax/scatter_linked_brush.py +++ b/tests/examples_arguments_syntax/scatter_linked_brush.py @@ -14,7 +14,7 @@ base = alt.Chart(source).mark_point().encode( y='Miles_per_Gallon', - color=alt.condition(brush, 'Origin', alt.ColorValue('gray')), + color=alt.when(brush).then("Origin").otherwise(alt.ColorValue("gray")), ).add_params( brush ).properties( diff --git a/tests/examples_arguments_syntax/scatter_linked_table.py b/tests/examples_arguments_syntax/scatter_linked_table.py index 93777b751..e17c4dbb0 100644 --- a/tests/examples_arguments_syntax/scatter_linked_table.py +++ b/tests/examples_arguments_syntax/scatter_linked_table.py @@ -18,7 +18,7 @@ points = alt.Chart(source).mark_point().encode( x='Horsepower:Q', y='Miles_per_Gallon:Q', - color=alt.condition(brush, alt.value('steelblue'), alt.value('grey')) + color=alt.when(brush).then(alt.value("steelblue")).otherwise(alt.value("grey")) ).add_params(brush) # Base chart for data tables diff --git a/tests/examples_arguments_syntax/scatter_point_paths_hover.py b/tests/examples_arguments_syntax/scatter_point_paths_hover.py index ee755b9e0..aea0960f6 100644 --- a/tests/examples_arguments_syntax/scatter_point_paths_hover.py +++ b/tests/examples_arguments_syntax/scatter_point_paths_hover.py @@ -53,14 +53,15 @@ "datum.country !== 'North Korea' && datum.country !== 'South Korea'" ) +search_matches = alt.expr.test(alt.expr.regexp(search_box, "i"), alt.datum.country) +opacity = ( + alt.when(hover_point_opacity, search_matches) + .then(alt.value(0.8)) + .otherwise(alt.value(0.1)) +) # Points that are always visible (filtered by slider and search) visible_points = base.mark_circle(size=100).encode( - opacity=alt.condition( - hover_point_opacity - & alt.expr.test(alt.expr.regexp(search_box, 'i'), alt.datum.country), - alt.value(0.8), - alt.value(0.1) - ) + opacity=opacity ).transform_filter( x_select ).add_params( @@ -69,6 +70,7 @@ x_select ) +when_hover = alt.when(hover) hover_line = alt.layer( # Line layer base.mark_trail().encode( @@ -81,12 +83,12 @@ scale=alt.Scale(domain=[1955, 2005], range=[1, 12]), legend=None ), - opacity=alt.condition(hover, alt.value(0.3), alt.value(0)), + opacity=when_hover.then(alt.value(0.3)).otherwise(alt.value(0)), color=alt.value('#222222') ), # Point layer base.mark_point(size=50).encode( - opacity=alt.condition(hover, alt.value(0.8), alt.value(0)), + opacity=when_hover.then(alt.value(0.8)).otherwise(alt.value(0)), ) ) @@ -108,7 +110,7 @@ y='life_expect:Q', text='country:N', color=alt.value('black'), - opacity=alt.condition(hover, alt.value(1), alt.value(0)) + opacity=when_hover.then(alt.value(1)).otherwise(alt.value(0)) ).transform_window( rank='rank(life_expect)', sort=[alt.SortField('life_expect', order='descending')], diff --git a/tests/examples_arguments_syntax/scatter_with_histogram.py b/tests/examples_arguments_syntax/scatter_with_histogram.py index dda40dec0..40cb65c2b 100644 --- a/tests/examples_arguments_syntax/scatter_with_histogram.py +++ b/tests/examples_arguments_syntax/scatter_with_histogram.py @@ -42,7 +42,7 @@ mag = alt.Chart().mark_bar().encode( x='mbin:N', y="count()", - color=alt.condition(pts, alt.value("black"), alt.value("lightgray")) + color=alt.when(pts).then(alt.value("black")).otherwise(alt.value("lightgray")) ).properties( width=300, height=300 diff --git a/tests/examples_arguments_syntax/scatter_with_layered_histogram.py b/tests/examples_arguments_syntax/scatter_with_layered_histogram.py index 2268b055c..087d9b405 100644 --- a/tests/examples_arguments_syntax/scatter_with_layered_histogram.py +++ b/tests/examples_arguments_syntax/scatter_with_layered_histogram.py @@ -30,7 +30,11 @@ color_scale = alt.Scale(domain=['M', 'F'], range=['#1FC3AA', '#8624F5']) - +color = ( + alt.when(selector) + .then(alt.Color("gender:N", scale=color_scale)) + .otherwise(alt.value("lightgray")) +) base = alt.Chart(source).properties( width=250, height=250 @@ -39,11 +43,7 @@ points = base.mark_point(filled=True, size=200).encode( x=alt.X('mean(height):Q', scale=alt.Scale(domain=[0,84])), y=alt.Y('mean(weight):Q', scale=alt.Scale(domain=[0,250])), - color=alt.condition( - selector, - 'gender:N', - alt.value('lightgray'), - scale=color_scale), + color=color, ) hists = base.mark_bar(opacity=0.5, thickness=100).encode( diff --git a/tests/examples_arguments_syntax/scatter_with_minimap.py b/tests/examples_arguments_syntax/scatter_with_minimap.py index a18a599cd..df8a9fd44 100644 --- a/tests/examples_arguments_syntax/scatter_with_minimap.py +++ b/tests/examples_arguments_syntax/scatter_with_minimap.py @@ -21,7 +21,7 @@ .encode( x="date:T", y="temp_max:Q", - color=alt.condition(zoom, "weather", alt.value("lightgray")), + color=alt.when(zoom).then("weather").otherwise(alt.value("lightgray")), ) .properties( width=200, diff --git a/tests/examples_arguments_syntax/seattle_weather_interactive.py b/tests/examples_arguments_syntax/seattle_weather_interactive.py index 798cc4780..63e93d011 100644 --- a/tests/examples_arguments_syntax/seattle_weather_interactive.py +++ b/tests/examples_arguments_syntax/seattle_weather_interactive.py @@ -28,7 +28,7 @@ title='Maximum Daily Temperature (C)', scale=alt.Scale(domain=[-5, 40]) ), - color=alt.condition(brush, color, alt.value('lightgray')), + color=alt.when(brush).then(color).otherwise(alt.value("lightgray")), size=alt.Size('precipitation:Q', scale=alt.Scale(range=[5, 200])) ).properties( width=550, @@ -43,7 +43,7 @@ bars = alt.Chart().mark_bar().encode( x='count()', y='weather:N', - color=alt.condition(click, color, alt.value('lightgray')), + color=alt.when(click).then(color).otherwise(alt.value("lightgray")), ).transform_filter( brush ).properties( diff --git a/tests/examples_arguments_syntax/select_detail.py b/tests/examples_arguments_syntax/select_detail.py index 500668c4f..9165e727f 100644 --- a/tests/examples_arguments_syntax/select_detail.py +++ b/tests/examples_arguments_syntax/select_detail.py @@ -42,6 +42,11 @@ # Data is prepared, now make a chart selector = alt.selection_point(fields=['id']) +color = ( + alt.when(selector) + .then(alt.Color("id:O", legend=None)) + .otherwise(alt.value("lightgray")) +) base = alt.Chart(data).properties( width=250, @@ -51,7 +56,7 @@ points = base.mark_point(filled=True, size=200).encode( x='mean(x)', y='mean(y)', - color=alt.condition(selector, 'id:O', alt.value('lightgray'), legend=None), + color=color, ) line = base.mark_line().encode( diff --git a/tests/examples_arguments_syntax/selection_histogram.py b/tests/examples_arguments_syntax/selection_histogram.py index dc0ccab8b..155b9fc68 100644 --- a/tests/examples_arguments_syntax/selection_histogram.py +++ b/tests/examples_arguments_syntax/selection_histogram.py @@ -16,7 +16,7 @@ points = alt.Chart(source).mark_point().encode( x='Horsepower:Q', y='Miles_per_Gallon:Q', - color=alt.condition(brush, 'Origin:N', alt.value('lightgray')) + color=alt.when(brush).then("Origin:N").otherwise(alt.value("lightgray")) ).add_params( brush ) diff --git a/tests/examples_arguments_syntax/selection_layer_bar_month.py b/tests/examples_arguments_syntax/selection_layer_bar_month.py index 43f4e97d2..e97914765 100644 --- a/tests/examples_arguments_syntax/selection_layer_bar_month.py +++ b/tests/examples_arguments_syntax/selection_layer_bar_month.py @@ -15,7 +15,7 @@ bars = alt.Chart().mark_bar().encode( x='month(date):O', y='mean(precipitation):Q', - opacity=alt.condition(brush, alt.OpacityValue(1), alt.OpacityValue(0.7)), + opacity = alt.when(brush).then(alt.value(1)).otherwise(alt.value(0.7)), ).add_params( brush ) diff --git a/tests/examples_arguments_syntax/selection_zorder.py b/tests/examples_arguments_syntax/selection_zorder.py index c8e3bd84a..6f6d7c93d 100644 --- a/tests/examples_arguments_syntax/selection_zorder.py +++ b/tests/examples_arguments_syntax/selection_zorder.py @@ -16,18 +16,19 @@ cars = data.cars.url hover = alt.selection_point(on='pointerover', nearest=True, empty=False) +when_hover = alt.when(hover) chart = alt.Chart(cars, title='Selection obscured by other points').mark_circle(opacity=1).encode( x='Horsepower:Q', y='Miles_per_Gallon:Q', - color=alt.condition(hover, alt.value('coral'), alt.value('lightgray')), - size=alt.condition(hover, alt.value(300), alt.value(30)) + color=when_hover.then(alt.value("coral")).otherwise(alt.value("lightgray")), + size=when_hover.then(alt.value(300)).otherwise(alt.value(30)) ).add_params( hover ) chart | chart.encode( - order=alt.condition(hover, alt.value(1), alt.value(0)) + order=when_hover.then(alt.value(1)).otherwise(alt.value(0)) ).properties( title='Selection brought to front' ) diff --git a/tests/examples_arguments_syntax/slider_cutoff.py b/tests/examples_arguments_syntax/slider_cutoff.py index 19db77493..786268aeb 100644 --- a/tests/examples_arguments_syntax/slider_cutoff.py +++ b/tests/examples_arguments_syntax/slider_cutoff.py @@ -17,14 +17,12 @@ slider = alt.binding_range(min=0, max=100, step=1) cutoff = alt.param(bind=slider, value=50) +predicate = alt.datum.xval < cutoff 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 ) \ No newline at end of file diff --git a/tests/examples_arguments_syntax/us_employment.py b/tests/examples_arguments_syntax/us_employment.py index 51f56998f..2b084290e 100644 --- a/tests/examples_arguments_syntax/us_employment.py +++ b/tests/examples_arguments_syntax/us_employment.py @@ -21,6 +21,7 @@ "president": "Obama" } ]) +predicate = alt.datum.nonfarm_change > 0 bars = alt.Chart( source, @@ -28,11 +29,7 @@ ).mark_bar().encode( x=alt.X("month:T", title=""), y=alt.Y("nonfarm_change:Q", title="Change in non-farm employment (in thousands)"), - color=alt.condition( - alt.datum.nonfarm_change > 0, - alt.value("steelblue"), - alt.value("orange") - ) + color=alt.when(predicate).then(alt.value("steelblue")).otherwise(alt.value("orange")), ) rule = alt.Chart(presidents).mark_rule( diff --git a/tests/examples_arguments_syntax/us_state_capitals.py b/tests/examples_arguments_syntax/us_state_capitals.py index ad83b8a23..7598dd54c 100644 --- a/tests/examples_arguments_syntax/us_state_capitals.py +++ b/tests/examples_arguments_syntax/us_state_capitals.py @@ -32,12 +32,12 @@ text = base.mark_text(dy=-5, align='right').encode( alt.Text('city', type='nominal'), - opacity=alt.condition(~hover, alt.value(0), alt.value(1)) + opacity=alt.when(~hover).then(alt.value(0)).otherwise(alt.value(1)) ) points = base.mark_point().encode( color=alt.value('black'), - size=alt.condition(~hover, alt.value(30), alt.value(100)) + size=alt.when(~hover).then(alt.value(30)).otherwise(alt.value(100)) ).add_params(hover) background + points + text diff --git a/tests/examples_arguments_syntax/waterfall_chart.py b/tests/examples_arguments_syntax/waterfall_chart.py index 50f8718f4..bc01e04d4 100644 --- a/tests/examples_arguments_syntax/waterfall_chart.py +++ b/tests/examples_arguments_syntax/waterfall_chart.py @@ -27,36 +27,43 @@ ] source = pd.DataFrame(data) +# Define frequently referenced fields +amount = alt.datum.amount +label = alt.datum.label +window_lead_label = alt.datum.window_lead_label +window_sum_amount = alt.datum.window_sum_amount + +# Define frequently referenced/long expressions +calc_prev_sum = alt.expr.if_(label == "End", 0, window_sum_amount - amount) +calc_amount = alt.expr.if_(label == "End", window_sum_amount, amount) +calc_text_amount = ( + alt.expr.if_((label != "Begin") & (label != "End") & calc_amount > 0, "+", "") + + calc_amount +) + # The "base_chart" defines the transform_window, transform_calculate, and X axis base_chart = alt.Chart(source).transform_window( window_sum_amount="sum(amount)", window_lead_label="lead(label)", ).transform_calculate( - calc_lead="datum.window_lead_label === null ? datum.label : datum.window_lead_label", - calc_prev_sum="datum.label === 'End' ? 0 : datum.window_sum_amount - datum.amount", - calc_amount="datum.label === 'End' ? datum.window_sum_amount : datum.amount", - calc_text_amount="(datum.label !== 'Begin' && datum.label !== 'End' && datum.calc_amount > 0 ? '+' : '') + datum.calc_amount", - calc_center="(datum.window_sum_amount + datum.calc_prev_sum) / 2", - calc_sum_dec="datum.window_sum_amount < datum.calc_prev_sum ? datum.window_sum_amount : ''", - calc_sum_inc="datum.window_sum_amount > datum.calc_prev_sum ? datum.window_sum_amount : ''", + calc_lead=alt.expr.if_((window_lead_label == None), label, window_lead_label), + calc_prev_sum=calc_prev_sum, + calc_amount=calc_amount, + calc_text_amount=calc_text_amount, + calc_center=(window_sum_amount + calc_prev_sum) / 2, + calc_sum_dec=alt.expr.if_(window_sum_amount < calc_prev_sum, window_sum_amount, ""), + calc_sum_inc=alt.expr.if_(window_sum_amount > calc_prev_sum, window_sum_amount, ""), ).encode( - x=alt.X( - "label:O", - axis=alt.Axis(title="Months", labelAngle=0), - sort=None, - ) + x=alt.X("label:O", axis=alt.Axis(title="Months", labelAngle=0), sort=None) ) -# alt.condition does not support multiple if else conditions which is why -# we use a dictionary instead. See https://stackoverflow.com/a/66109641 -# for more information -color_coding = { - "condition": [ - {"test": "datum.label === 'Begin' || datum.label === 'End'", "value": "#878d96"}, - {"test": "datum.calc_amount < 0", "value": "#24a148"}, - ], - "value": "#fa4d56", -} +color_coding = ( + alt.when((label == "Begin") | (label == "End")) + .then(alt.value("#878d96")) + .when(calc_amount < 0) + .then(alt.value("#24a148")) + .otherwise(alt.value("#fa4d56")) +) bar = base_chart.mark_bar(size=45).encode( y=alt.Y("calc_prev_sum:Q", title="Amount"), @@ -65,28 +72,19 @@ ) # The "rule" chart is for the horizontal lines that connect the bars -rule = base_chart.mark_rule( - xOffset=-22.5, - x2Offset=22.5, -).encode( +rule = base_chart.mark_rule(xOffset=-22.5, x2Offset=22.5).encode( y="window_sum_amount:Q", x2="calc_lead", ) # Add values as text -text_pos_values_top_of_bar = base_chart.mark_text( - baseline="bottom", - dy=-4 -).encode( +text_pos_values_top_of_bar = base_chart.mark_text(baseline="bottom", dy=-4).encode( text=alt.Text("calc_sum_inc:N"), - y="calc_sum_inc:Q" + y="calc_sum_inc:Q", ) -text_neg_values_bot_of_bar = base_chart.mark_text( - baseline="top", - dy=4 -).encode( +text_neg_values_bot_of_bar = base_chart.mark_text(baseline="top", dy=4).encode( text=alt.Text("calc_sum_dec:N"), - y="calc_sum_dec:Q" + y="calc_sum_dec:Q", ) text_bar_values_mid_of_bar = base_chart.mark_text(baseline="middle").encode( text=alt.Text("calc_text_amount:N"), diff --git a/tests/examples_methods_syntax/candlestick_chart.py b/tests/examples_methods_syntax/candlestick_chart.py index 47e713abb..c001f7ddf 100644 --- a/tests/examples_methods_syntax/candlestick_chart.py +++ b/tests/examples_methods_syntax/candlestick_chart.py @@ -12,12 +12,11 @@ source = data.ohlc() -open_close_color = alt.condition( - "datum.open <= datum.close", - alt.value("#06982d"), - alt.value("#ae1325") +open_close_color = ( + alt.when("datum.open <= datum.close") + .then(alt.value("#06982d")) + .otherwise(alt.value("#ae1325")) ) - base = alt.Chart(source).encode( alt.X('date:T') .axis(format='%m/%d', labelAngle=-45) diff --git a/tests/examples_methods_syntax/interactive_column_selection.py b/tests/examples_methods_syntax/interactive_column_selection.py index a74fba609..d202f433d 100644 --- a/tests/examples_methods_syntax/interactive_column_selection.py +++ b/tests/examples_methods_syntax/interactive_column_selection.py @@ -37,7 +37,7 @@ alt.X('level_0').title(None), alt.Y('level_1').title(None), alt.Color('correlation').scale(domain=[-1, 1], scheme='blueorange'), - opacity=alt.condition(select_x & select_y, alt.value(1), alt.value(0.4)) + opacity=alt.when(select_x, select_y).then(alt.value(1)).otherwise(alt.value(0.4)), ).add_params( select_x, select_y ) diff --git a/tests/examples_methods_syntax/interactive_cross_highlight.py b/tests/examples_methods_syntax/interactive_cross_highlight.py index 860a385c2..97dccb314 100644 --- a/tests/examples_methods_syntax/interactive_cross_highlight.py +++ b/tests/examples_methods_syntax/interactive_cross_highlight.py @@ -29,7 +29,7 @@ bar = alt.Chart(source, width=550, height=200).mark_bar().encode( x='Major_Genre:N', y='count()', - color=alt.condition(pts, alt.ColorValue("steelblue"), alt.ColorValue("grey")) + color=alt.when(pts).then(alt.ColorValue("steelblue")).otherwise(alt.ColorValue("grey")) ).add_params(pts) alt.vconcat( diff --git a/tests/examples_methods_syntax/interactive_legend.py b/tests/examples_methods_syntax/interactive_legend.py index 80c47cf11..e6a6e36f7 100644 --- a/tests/examples_methods_syntax/interactive_legend.py +++ b/tests/examples_methods_syntax/interactive_legend.py @@ -17,7 +17,7 @@ alt.X('yearmonth(date):T').axis(domain=False, format='%Y', tickSize=0), alt.Y('sum(count):Q').stack('center').axis(None), alt.Color('series:N').scale(scheme='category20b'), - opacity=alt.condition(selection, alt.value(1), alt.value(0.2)) + opacity=alt.when(selection).then(alt.value(1)).otherwise(alt.value(0.2)) ).add_params( selection ) diff --git a/tests/examples_methods_syntax/interval_selection_map_quakes.py b/tests/examples_methods_syntax/interval_selection_map_quakes.py index b45afe8da..f4e89ad65 100644 --- a/tests/examples_methods_syntax/interval_selection_map_quakes.py +++ b/tests/examples_methods_syntax/interval_selection_map_quakes.py @@ -38,7 +38,7 @@ ).mark_circle(opacity=0.35, tooltip=True).encode( longitude="lon:Q", latitude="lat:Q", - color=alt.condition(brush, alt.value("goldenrod"), alt.value("steelblue")), + color=alt.when(brush).then(alt.value("goldenrod")).otherwise(alt.value("steelblue")), size=alt.Size("mag:Q").scale(type="pow", range=[1, 1000], domain=[0, 7], exponent=4), ).add_params(brush) diff --git a/tests/examples_methods_syntax/lasagna_plot.py b/tests/examples_methods_syntax/lasagna_plot.py index 0da7c44fd..31ab3ee40 100644 --- a/tests/examples_methods_syntax/lasagna_plot.py +++ b/tests/examples_methods_syntax/lasagna_plot.py @@ -8,10 +8,10 @@ source = data.stocks() -color_condition = alt.condition( - "month(datum.value) == 1 && date(datum.value) == 1", - alt.value("black"), - alt.value(None), +color_condition = ( + alt.when(alt.expr.month("datum.value") == 1, alt.expr.date("datum.value") == 1) + .then(alt.value("black")) + .otherwise(alt.value(None)) ) alt.Chart(source, width=300, height=100).transform_filter( diff --git a/tests/examples_methods_syntax/layered_heatmap_text.py b/tests/examples_methods_syntax/layered_heatmap_text.py index 7a61c08cb..ba56f8539 100644 --- a/tests/examples_methods_syntax/layered_heatmap_text.py +++ b/tests/examples_methods_syntax/layered_heatmap_text.py @@ -27,14 +27,15 @@ .title("Mean of Horsepower") ) +color = ( + alt.when(alt.datum.mean_horsepower > 150) + .then(alt.value("black")) + .otherwise(alt.value("white")) +) + # Configure text text = base.mark_text(baseline='middle').encode( - alt.Text('mean_horsepower:Q', format=".0f"), - color=alt.condition( - alt.datum.mean_horsepower > 150, - alt.value('black'), - alt.value('white') - ) + alt.Text('mean_horsepower:Q', format=".0f"), color=color ) # Draw the chart diff --git a/tests/examples_methods_syntax/multiline_highlight.py b/tests/examples_methods_syntax/multiline_highlight.py index c23bd0372..bbc7634e8 100644 --- a/tests/examples_methods_syntax/multiline_highlight.py +++ b/tests/examples_methods_syntax/multiline_highlight.py @@ -29,7 +29,7 @@ ) lines = base.mark_line().encode( - size=alt.condition(~highlight, alt.value(1), alt.value(3)) + size=alt.when(~highlight).then(alt.value(1)).otherwise(alt.value(3)) ) points + lines diff --git a/tests/examples_methods_syntax/multiline_tooltip.py b/tests/examples_methods_syntax/multiline_tooltip.py index 12ac92bf0..d2bd7ff8f 100644 --- a/tests/examples_methods_syntax/multiline_tooltip.py +++ b/tests/examples_methods_syntax/multiline_tooltip.py @@ -41,15 +41,16 @@ ).add_params( nearest ) +when_near = alt.when(nearest) # Draw points on the line, and highlight based on selection points = line.mark_point().encode( - opacity=alt.condition(nearest, alt.value(1), alt.value(0)) + opacity=when_near.then(alt.value(1)).otherwise(alt.value(0)) ) # Draw text labels near the points, and highlight based on selection text = line.mark_text(align="left", dx=5, dy=-5).encode( - text=alt.condition(nearest, "y:Q", alt.value(" ")) + text=when_near.then("y:Q").otherwise(alt.value(" ")) ) # Draw a rule at the location of the selection diff --git a/tests/examples_methods_syntax/multiline_tooltip_standard.py b/tests/examples_methods_syntax/multiline_tooltip_standard.py index 990aa2015..bbab79d46 100644 --- a/tests/examples_methods_syntax/multiline_tooltip_standard.py +++ b/tests/examples_methods_syntax/multiline_tooltip_standard.py @@ -28,10 +28,11 @@ y="y:Q", color="category:N" ) +when_near = alt.when(nearest) # Draw points on the line, and highlight based on selection points = line.mark_point().encode( - opacity=alt.condition(nearest, alt.value(1), alt.value(0)) + opacity=when_near.then(alt.value(1)).otherwise(alt.value(0)) ) # Draw a rule at the location of the selection @@ -41,7 +42,7 @@ groupby=["x"] ).mark_rule(color="gray").encode( x="x:Q", - opacity=alt.condition(nearest, alt.value(0.3), alt.value(0)), + opacity=when_near.then(alt.value(0.3)).otherwise(alt.value(0)), tooltip=[alt.Tooltip(c, type="quantitative") for c in columns], ).add_params(nearest) diff --git a/tests/examples_methods_syntax/multiple_interactions.py b/tests/examples_methods_syntax/multiple_interactions.py index 0d0ff0ef9..cab614148 100644 --- a/tests/examples_methods_syntax/multiple_interactions.py +++ b/tests/examples_methods_syntax/multiple_interactions.py @@ -62,32 +62,32 @@ rating_radio = alt.binding_radio(options=ratings, name="Rating") rating_select = alt.selection_point(fields=['MPAA_Rating'], bind=rating_radio) -rating_color_condition = alt.condition( - rating_select, - alt.Color('MPAA_Rating:N').legend(None), - alt.value('lightgray') +rating_color = ( + alt.when(rating_select) + .then(alt.Color("MPAA_Rating:N").legend(None)) + .otherwise(alt.value("lightgray")) ) highlight_ratings = base.add_params( rating_select ).encode( - color=rating_color_condition + color=rating_color ).properties(title="Radio Button Highlighting") # Boolean selection for format changes input_checkbox = alt.binding_checkbox(name="Big Budget Films ") checkbox_selection = alt.param(bind=input_checkbox) -size_checkbox_condition = alt.condition( - checkbox_selection, - alt.Size('Big_Budget_Film:N').scale(range=[25, 150]), - alt.SizeValue(25) +size_checkbox = ( + alt.when(checkbox_selection) + .then(alt.Size('Big_Budget_Film:N').scale(range=[25, 150])) + .otherwise(alt.value(25)) ) budget_sizing = base.add_params( checkbox_selection ).encode( - size=size_checkbox_condition + size=size_checkbox ).properties(title="Checkbox Formatting") (filter_year | budget_sizing) & (highlight_ratings | filter_genres) diff --git a/tests/examples_methods_syntax/scatter_linked_table.py b/tests/examples_methods_syntax/scatter_linked_table.py index 99979e074..d2fd3f317 100644 --- a/tests/examples_methods_syntax/scatter_linked_table.py +++ b/tests/examples_methods_syntax/scatter_linked_table.py @@ -18,7 +18,7 @@ points = alt.Chart(source).mark_point().encode( x='Horsepower:Q', y='Miles_per_Gallon:Q', - color=alt.condition(brush, alt.value('steelblue'), alt.value('grey')) + color=alt.when(brush).then(alt.value("steelblue")).otherwise(alt.value("grey")) ).add_params(brush) # Base chart for data tables diff --git a/tests/examples_methods_syntax/scatter_point_paths_hover.py b/tests/examples_methods_syntax/scatter_point_paths_hover.py index a6cc747c7..c6a9c5f19 100644 --- a/tests/examples_methods_syntax/scatter_point_paths_hover.py +++ b/tests/examples_methods_syntax/scatter_point_paths_hover.py @@ -53,14 +53,15 @@ "datum.country !== 'North Korea' && datum.country !== 'South Korea'" ) +search_matches = alt.expr.test(alt.expr.regexp(search_box, "i"), alt.datum.country) +opacity = ( + alt.when(hover_point_opacity, search_matches) + .then(alt.value(0.8)) + .otherwise(alt.value(0.1)) +) # Points that are always visible (filtered by slider and search) visible_points = base.mark_circle(size=100).encode( - opacity=alt.condition( - hover_point_opacity - & alt.expr.test(alt.expr.regexp(search_box, 'i'), alt.datum.country), - alt.value(0.8), - alt.value(0.1) - ) + opacity=opacity ).transform_filter( x_select ).add_params( @@ -69,17 +70,18 @@ x_select ) +when_hover = alt.when(hover) hover_line = alt.layer( # Line layer base.mark_trail().encode( alt.Order('year:Q').sort('ascending'), alt.Size('year:Q').scale(domain=[1955, 2005], range=[1, 12]).legend(None), - opacity=alt.condition(hover, alt.value(0.3), alt.value(0)), + opacity=when_hover.then(alt.value(0.3)).otherwise(alt.value(0)), color=alt.value('#222222') ), # Point layer base.mark_point(size=50).encode( - opacity=alt.condition(hover, alt.value(0.8), alt.value(0)), + opacity=when_hover.then(alt.value(0.8)).otherwise(alt.value(0)), ) ) @@ -101,7 +103,7 @@ y='life_expect:Q', text='country:N', color=alt.value('black'), - opacity=alt.condition(hover, alt.value(1), alt.value(0)) + opacity=when_hover.then(alt.value(1)).otherwise(alt.value(0)) ).transform_window( rank='rank(life_expect)', sort=[alt.SortField('life_expect', order='descending')], diff --git a/tests/examples_methods_syntax/scatter_with_layered_histogram.py b/tests/examples_methods_syntax/scatter_with_layered_histogram.py index 2cec75902..ce928f338 100644 --- a/tests/examples_methods_syntax/scatter_with_layered_histogram.py +++ b/tests/examples_methods_syntax/scatter_with_layered_histogram.py @@ -30,7 +30,11 @@ color_scale = alt.Scale(domain=['M', 'F'], range=['#1FC3AA', '#8624F5']) - +color = ( + alt.when(selector) + .then(alt.Color("gender:N").scale(color_scale)) + .otherwise(alt.value("lightgray")) +) base = alt.Chart(source).properties( width=250, height=250 @@ -39,11 +43,7 @@ points = base.mark_point(filled=True, size=200).encode( alt.X('mean(height):Q').scale(domain=[0,84]), alt.Y('mean(weight):Q').scale(domain=[0,250]), - color=alt.condition( - selector, - 'gender:N', - alt.value('lightgray'), - scale=color_scale), + color=color, ) hists = base.mark_bar(opacity=0.5, thickness=100).encode( diff --git a/tests/examples_methods_syntax/scatter_with_minimap.py b/tests/examples_methods_syntax/scatter_with_minimap.py index 0ad0c634c..9faafa720 100644 --- a/tests/examples_methods_syntax/scatter_with_minimap.py +++ b/tests/examples_methods_syntax/scatter_with_minimap.py @@ -21,7 +21,7 @@ .encode( x="date:T", y="temp_max:Q", - color=alt.condition(zoom, "weather", alt.value("lightgray")), + color=alt.when(zoom).then("weather").otherwise(alt.value("lightgray")), ) .properties( width=200, diff --git a/tests/examples_methods_syntax/seattle_weather_interactive.py b/tests/examples_methods_syntax/seattle_weather_interactive.py index 8c59a83d9..83c7f3e6b 100644 --- a/tests/examples_methods_syntax/seattle_weather_interactive.py +++ b/tests/examples_methods_syntax/seattle_weather_interactive.py @@ -29,7 +29,7 @@ .title('Maximum Daily Temperature (C)') .scale(domain=[-5, 40]), alt.Size('precipitation:Q').scale(range=[5, 200]), - color=alt.condition(brush, color, alt.value('lightgray')), + color=alt.when(brush).then(color).otherwise(alt.value("lightgray")), ).properties( width=550, height=300 @@ -43,7 +43,7 @@ bars = alt.Chart().mark_bar().encode( x='count()', y='weather:N', - color=alt.condition(click, color, alt.value('lightgray')), + color=alt.when(click).then(color).otherwise(alt.value("lightgray")), ).transform_filter( brush ).properties( diff --git a/tests/examples_methods_syntax/select_detail.py b/tests/examples_methods_syntax/select_detail.py index 58bdb9dfd..10140bae8 100644 --- a/tests/examples_methods_syntax/select_detail.py +++ b/tests/examples_methods_syntax/select_detail.py @@ -42,6 +42,11 @@ # Data is prepared, now make a chart selector = alt.selection_point(fields=['id']) +color = ( + alt.when(selector) + .then(alt.Color("id:O").legend(None)) + .otherwise(alt.value("lightgray")) +) base = alt.Chart(data).properties( width=250, @@ -51,7 +56,7 @@ points = base.mark_point(filled=True, size=200).encode( x='mean(x)', y='mean(y)', - color=alt.condition(selector, 'id:O', alt.value('lightgray'), legend=None), + color=color, ) line = base.mark_line().encode( diff --git a/tests/examples_methods_syntax/us_employment.py b/tests/examples_methods_syntax/us_employment.py index 775973abf..24272d44d 100644 --- a/tests/examples_methods_syntax/us_employment.py +++ b/tests/examples_methods_syntax/us_employment.py @@ -21,6 +21,7 @@ "president": "Obama" } ]) +predicate = alt.datum.nonfarm_change > 0 bars = alt.Chart( source, @@ -28,11 +29,7 @@ ).mark_bar().encode( alt.X("month:T").title(""), alt.Y("nonfarm_change:Q").title("Change in non-farm employment (in thousands)"), - color=alt.condition( - alt.datum.nonfarm_change > 0, - alt.value("steelblue"), - alt.value("orange") - ) + color=alt.when(predicate).then(alt.value("steelblue")).otherwise(alt.value("orange")), ) rule = alt.Chart(presidents).mark_rule( diff --git a/tests/examples_methods_syntax/us_state_capitals.py b/tests/examples_methods_syntax/us_state_capitals.py index d9f1390a2..9803cafc5 100644 --- a/tests/examples_methods_syntax/us_state_capitals.py +++ b/tests/examples_methods_syntax/us_state_capitals.py @@ -32,12 +32,12 @@ text = base.mark_text(dy=-5, align='right').encode( alt.Text('city:N'), - opacity=alt.condition(~hover, alt.value(0), alt.value(1)) + opacity=alt.when(~hover).then(alt.value(0)).otherwise(alt.value(1)) ) points = base.mark_point().encode( color=alt.value('black'), - size=alt.condition(~hover, alt.value(30), alt.value(100)) + size=alt.when(~hover).then(alt.value(30)).otherwise(alt.value(100)) ).add_params(hover) background + points + text