altair
altair copied to clipboard
Boxplots with filter transform based on selection don't work
I'm have a series of metrics that I've computed for different sample groups in my data, and I want to compare the distributions of a given metric with a boxplot for each sample group, using a dropdown list to choose the metric being compared. But when I do the following, I get a JavaScript Error:
import altair as alt, pandas as pd
import numpy as np
np.random.seed(431)
metrics = pd.DataFrame({
'metric1': np.random.normal(30, 20, 100),
'metric2': np.random.lognormal(2, 1, 100),
'metric3': np.random.uniform(0, 80, 100),
'group': np.random.choice(['A', 'B'], 100)
})
metrics = pd.melt(
metrics,
id_vars='group',
var_name='metric',
value_name='value'
)
group_dropdown = alt.binding_select(options=['metric1', 'metric2', 'metric3'])
group_selection = alt.selection_single(
fields=['metric'],
bind=group_dropdown,
name='Group ',
init={'metric': 'metric1'}
)
distribution_boxes = alt.Chart(metrics).mark_boxplot(size=30).encode(
x='group',
y=alt.Y('value', title='metric1'),
color='group',
).properties(
width=150,
height=300
).transform_filter(
group_selection
).add_selection(
group_selection
)
distribution_boxes
When I change the mark type to mark_tick()
, the plot renders correctly:
distribution_ticks = alt.Chart(metrics).mark_tick(size=30).encode(
x='group',
y=alt.Y('value', title='metric1'),
color='group',
).properties(
width=150,
height=300
).transform_filter(
group_selection
).add_selection(
group_selection
)
distribution_ticks
Is this an issue with Altair, or with vega-lite?
Thanks for your help!
Hi. I ran your boxplot code and checked the browser console and found this warning: WARN Selection not supported for boxplot yet.
. This is probably an issue from Vega-lite and why your boxplot doesn't render.
If you haven't tried this yet, I think an ok alternative to the dropdown list is to have all 3 metrics as columns like so
alt.Chart(metrics).mark_boxplot(size=30).encode(
x='group',
y='value',
color='group',
column='metric'
).properties(width=100)
Hi @baogianghoangvu, thanks for looking into this. I figured it probably wasn't implemented in vega-lite yet, but I don't know much about JS and I didn't think to check the browser console- I'll remember that next time I have an issue.
Your suggestion to use the column channel is a good one, but in my actual use case I have another variable that I'm faceting via columns. I guess I could use the row channel too, but I was trying to keep the chart from getting too busy.
@carusov This is being tracked in https://github.com/vega/vega-lite/issues/3702 and can become available in Altair after it is implemented in Vega-Lite.
Hi @joelostblom, is there by any chance an update regarding the interactive boxplot issue? I would like to be able to zoom in on my boxplot but the interactive function does not work, also adding a scale does not give the desired results (scale= {"domain": [0,50]})
Hi @devliegherec, this will only be available in Altair after the functionality has been added to Vega-Lite, so please follow https://github.com/vega/vega-lite/issues/3702.
Regarding zooming and domain not working, could you create a minimal reproducible example and post your question (ideally on stack overflow tagging it with 'altair') and I will see if there is a workaround?
Closing this as there is nothing to do on the Altair side of things, when this function is added to VL, it will be in an upcoming Altair release.
Although boxplots still don't support .interactive
or direct selections, it is possible to have a dropdown menu that changes the column that is plotted as you asked initially @carusov. This is based on the new example here in the docs:
import altair as alt
from vega_datasets import data
dropdown = alt.binding_select(
options=['Miles_per_Gallon', 'Displacement', 'Weight_in_lbs', 'Acceleration'],
name='X-axis column '
)
xcol_param = alt.param(
value='Miles_per_Gallon',
bind=dropdown
)
alt.Chart(data.cars.url).mark_boxplot().encode(
x=alt.X('x:Q', title=''),
y='Origin:N',
color='Origin:N'
).transform_calculate(
x=f'datum[{xcol_param.name}]'
).add_params(
xcol_param
)
Thanks for the update @joelostblom. I'm excited about the new features in the coming 5.0 release. I'm a long-time and heavy user of Altair, so I'm very grateful to you and all the contributors for continuing to develop and extend Vega-Altair.