Search code examples
altair

Is it possible to display one faceted chart in Altair at a time and toggle between different charts?


I'm working on a project for a class where I've been creating faceted scatterplots in Altair where each chart is a different type of food. I was wondering if it would be possible to still use these faceted charts but only display one at a time and give the user the ability to toggle between graphs instead of having each graph displayed one after the other? Here is a rough diagram of what I'm trying to do and here's the code I have now (and what the output looks like at the moment):

import altair as alt
from vega_datasets import data

hover = alt.selection_single(on='mouseover', nearest=True, empty='none')

base = alt.Chart("Food Nutrition Info Compiled.csv").encode(
    x='Energ_Kcal:N',
    y='Water_(g):Q',
    color=alt.condition(hover, 'Type:N', alt.value('lightgray'))
).properties(
    width=180,
    height=180,
)

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

text = base.mark_text(dy=-5).encode(
    text = 'Shrt_Desc:N',
    opacity = alt.condition(hover, alt.value(1), alt.value(0))
)

alt.layer(points, text).facet(
    'Type:N',
)

Thanks and I hope this makes sense!


Solution

  • Displaying one faceted chart at a time sounds the same as showing a single subset of the data at any one point. This is currently possible by creating a selection that is bound to e.g. a dropdown and the using that with transform_filter:

    import altair as alt
    from vega_datasets import data
    
    
    source = data.cars()
    
    dropdown_options = source['Origin'].unique().tolist()
    
    dropdown = alt.binding_select(
        options=dropdown_options,
        name='Origin '
    )
    selection = alt.selection_multi(
        fields=['Origin'],
        value=[{'Origin': dropdown_options[0]}],
        bind=dropdown
    )
    
    alt.Chart(source).mark_circle().encode(
        x=alt.X('Weight_in_lbs:Q', title=''),
        y='Horsepower',
        color='Origin',
    ).add_selection(
        selection
    ).transform_filter(
        selection
    )
    

    enter image description here