I have the following facet chart where the order of the facet panels is determined by the column foo
. I would like to add a drop-down box where I can select to dynamically update the sort order of the facet panels to be based on either the column foo
or the column bar
(see attempt below).
import altair as alt
import pandas as pd
from vega_datasets import data
df = data.cars()
add_df = pd.DataFrame({
"Origin": ["USA", "Europe", "Japan"],
"foo": [1, 2, 3],
"bar": [3, 2, 1],
})
df = df.merge(
add_df,
on="Origin",
how="inner",
)
chart = alt.Chart(df).mark_point().encode(
x="Cylinders:Q",
y="Displacement:Q",
color="Origin:N",
).facet(
facet=alt.Facet(
"Origin:N",
sort=alt.SortField("bar"),
),
)
facet_sorted_foo
To add the drop down box, this is what I tried, based on https://altair-viz.github.io/user_guide/interactions.html#data-driven-comparisons:
sort_dropdown = alt.binding_select(options=["foo", "bar"], name="Sort by ")
sort_select = alt.selection_point(
fields=["sortby"],
bind=sort_dropdown,
value=[{"sortby": "foo"}],
)
chart = alt.Chart(df).mark_point().encode(
x="Cylinders:Q",
y="Displacement:Q",
color="Origin:N",
).add_params(
sort_select,
).facet(
facet=alt.Facet(
"Origin:N",
sort=alt.SortField(sort_select.sortby),
),
)
But I get the following error:
Traceback (most recent call last):
File "/home/centre/regression/test.py", line 50, in <module>
sort=alt.SortField(sort_select.sortby),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/centre/.pyenv/versions/3.11.5/lib/python3.11/site-packages/altair/vegalite/v5/schema/core.py", line 16685, in __init__
super(SortField, self).__init__(field=field, order=order, **kwds)
File "/home/centre/.pyenv/versions/3.11.5/lib/python3.11/site-packages/altair/utils/schemapi.py", line 776, in __init__
self.to_dict(validate=True)
File "/home/centre/.pyenv/versions/3.11.5/lib/python3.11/site-packages/altair/utils/schemapi.py", line 983, in to_dict
raise SchemaValidationError(self, err) from None
altair.utils.schemapi.SchemaValidationError: '{'expr': 'param_1.sortby'}' is an invalid value for `field`. Valid values are of type 'string'.
Is there a way to directly access the value of the selection_point
and pass it as the sort field? It appears that the main difference between my question and the example (as well as https://github.com/vega/altair/issues/2014) is that I’m not using the intermediary of an alt.condition
expression.
centrecom716 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.