Search code examples
pythonaltairvega-lite

Scale Y axis of Altair chart to interactive legend selection


I've copied the interactive legend code from here: https://altair-viz.github.io/gallery/interactive_legend.html

The difference is that my data has different orders of magnitude for the different series, so it would be nice if, when we select a set of series (shift click), we zoom the graph so that it fills the window. Is this possible in Altair?

Current base:

base = (
        alt.Chart(source)
        .mark_line(point=alt.OverlayMarkDef(color="red"))
        .encode(
            x=alt.X("date:T", axis=alt.Axis(format='%m/%d/%Y, %H:%M')),
            y="value:Q",
            color="datatype:N",
            opacity=alt.condition(selection, alt.value(1), alt.value(0.2))
        ).add_selection(selection)
    )

Solution

  • You can achieve it by using your selection to filter the data passed to the plot via transform_filter.

    One this to keep in mind is that we have to pass a custom scale otherwise the filtered data will only show legends for the selected field which leads us to a deadlock.

    import altair as alt
    from vega_datasets import data
    
    source = data.unemployment_across_industries.url
    
    selection = alt.selection_multi(fields=['series'], bind='legend')
    # custom color scale otherwise, non-selected legends will disappear
    custom_scale = alt.Scale(domain=pd.read_json(source).series.unique().tolist())
    alt.Chart(source).mark_area().encode(
        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=custom_scale),
        opacity=alt.condition(selection, alt.value(1), alt.value(0.2))
    ).add_selection(
        selection
    ).transform_filter( # get only those selected series
        selection
    )
    

    enter image description here