Skip to content

feat: Support params to be passed inline to encodings#3993

Open
joelostblom wants to merge 4 commits intofeat/inline-calcfrom
feat/inline-params
Open

feat: Support params to be passed inline to encodings#3993
joelostblom wants to merge 4 commits intofeat/inline-calcfrom
feat/inline-params

Conversation

@joelostblom
Copy link
Copy Markdown
Contributor

@joelostblom joelostblom commented Apr 5, 2026

I will rebase after #3990 and #3991, so let's wait with merging until that.

This PR layers inline variable-parameter support on top of existing inline-calc behavior, so users can pass variable params directly in encodings without manually writing alt.datum[param].

Syntax now supported:

  • encode(x=param)
  • encode(alt.X(param).type("quantitative") (we usually have to set the type since it cannot be inferred when changed dynamically via a param)
  • encode(alt.X(param).title('My name')) (explicit title override respected)

Examples

import altair as alt
from altair.datasets import data


dropdown_y = alt.binding_select(
    options=['Species', 'Island', 'Sex'],
    name='Y-axis column '
)
param_y = alt.param(
    value='Species',
    bind=dropdown_y
)

dropdown_color = alt.binding_select(
    options=['Species', 'Island', 'Sex'],
    name='Color column '
)
param_color = alt.param(
    value='Species',
    bind=dropdown_color
)

# No explicit type needs to be set since the VL default is 'nominal'
alt.Chart(data.penguins.url).mark_circle().encode(
    alt.X('Beak Depth (mm):Q'),
    alt.Y(param_y).title(None),
    alt.YOffset(alt.expr.random()),
    alt.Color(param_color).title(None)
).add_params(
    param_y, param_color
)
image

Open the Chart in the Vega Editor

import altair as alt
from altair.datasets import data

cars = data.cars.url
dropdown = alt.binding_select(
    options=['Horsepower', 'Displacement', 'Weight_in_lbs', 'Acceleration'],
    name='X-axis column '
)
xcol_param = alt.param(
    value='Horsepower',
    bind=dropdown
)
# Quantitative type needs to be set explicitly
alt.Chart(data.cars.url).mark_circle().encode(
    x=alt.X(xcol_param).type('quantitative'),
    y='Miles_per_Gallon:Q',
    color='Origin:N'
).add_params(xcol_param)
image

Open the Chart in the Vega Editor

Details:

  • altair/utils/core.py:898
    • _wrap_in_channel() now detects Parameter(param_type="variable") and wraps as GetItemExpression("datum", param) before channel serialization.
  • altair/vegalite/v6/schema/channels.py:189
    • FieldChannelMixin.to_dict() converts variable parameters to datum getitem expressions in both shorthand and kwarg scan paths.
  • altair/expr/core.py:283
    • GetItemExpression.repr() now uses _js_repr(self.name) so parameter names are emitted as datum[xcol] (not Python repr of the parameter object).
  • altair/vegalite/v6/schema/channels.py:226
    • Inline-calc fast path now preserves explicit title (including None) when set on the channel.
  • tools/generate_schema_wrapper.py:135
    • Generator template updated so regeneration preserves the same parameter behavior in generated channels.py.

What I corrected/simplified:
- In FieldChannelMixin.to_dict (altair/vegalite/v6/schema/channels.py:163), I moved expression/variable-param handling before parsed-shorthand context setup.
- This removes the need for the previous context.pop("parsed_shorthand", None) workaround and avoids context leakage by design.
- Behavior is unchanged for normal field-string paths, but this is cleaner and less fragile.
What I added to tests:
- Added a missing regression test for the bare channel case:
  - encode(x=param) (not just encode(x=alt.X(param, ...)))
  - File: tests/vegalite/v6/test_api.py:2259
- This ensures _wrap_in_channel path for variable params is covered.
@mattijn
Copy link
Copy Markdown
Contributor

mattijn commented Apr 6, 2026

Great to have these (and other PRs) related to improving parameter and expressions in a pythonic way!

Will this also mean that expression based examples like this one: https://altair-viz.github.io/user_guide/marks/geoshape.html#expressions can be simplified?

@joelostblom
Copy link
Copy Markdown
Contributor Author

Glad to hear you like it!

Hmm, in that spec I don't think there is much simplification to be made. We could avoid the lon/lat/depth transform_calculate for encodings by using inline expressions directly in channels. But in this chart, lon is also reused in transform_filter, so keeping transform_calculate is still reasonable (compute once, reuse twice). We could move the other two inline but maybe it is more intuitive to see lat and lon computed in the same place.

An example of a spec that will be improved is the one from the encoding channel docs, which can be rewritten as the example in my initial comment instead (I will update the docs on this PR next).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants