[Python] How can I change the selections presented by an Altair chart based on filtering...

Discussão em 'Python' iniciado por Stack, Novembro 21, 2024.

  1. Stack

    Stack Membro Participativo

    Consider the following example:

    import sys
    import polars as pl
    import altair as alt
    import numpy as np


    # ============================================
    # Creating the dummy data dataframe

    channels = pl.DataFrame(pl.Series("channel", ["a", "b"]))
    flavors = pl.DataFrame(pl.Series("flavor", ["spicy", "mild"]))
    dates = pl.DataFrame(pl.Series("date", [0, 1]))

    flavors_dates = flavors.join(dates, how="cross")
    channels_flavors_dates = channels.join(flavors_dates, how="cross").filter(
    ~(pl.col.channel.eq("a") & pl.col.flavor.ne("spicy"))
    )

    rng = np.random.default_rng(seed=0)

    df = channels_flavors_dates.with_columns(
    pl.Series(
    "stock",
    rng.integers(0, 11, size=len(channels_flavors_dates)),
    )
    )

    sys.displayhook(df)

    # ============================================

    channel_selection = alt.selection_point(
    "channel_selection",
    fields=["channel"],
    bind=alt.binding_select(
    options=list(df["channel"].unique()), name="channel_selector"
    ),
    )

    # the problem is that this is initialized with too many flavor options, as it is
    # insensitive to the channel selection
    flavor_selection = alt.selection_point(
    "flavor_selection",
    fields=["flavor"],
    # options is a required property...
    bind=alt.binding_select(
    options=list(df["flavor"].unique()), name="flavor_selector"
    ),
    )

    alt.Chart(df).mark_bar().encode(alt.X("date:O"), alt.Y("stock:Q")).add_params(
    channel_selection, flavor_selection
    ).transform_filter(channel_selection).transform_filter(flavor_selection)


    The dummy dataframe created is:

    shape: (6, 4)
    ┌─────────┬────────┬──────┬───────┐
    │ channel ┆ flavor ┆ date ┆ stock │
    │ --- ┆ --- ┆ --- ┆ --- │
    │ str ┆ str ┆ i64 ┆ i64 │
    ╞═════════╪════════╪══════╪═══════╡
    │ a ┆ spicy ┆ 0 ┆ 9 │
    │ a ┆ spicy ┆ 1 ┆ 7 │
    │ b ┆ spicy ┆ 0 ┆ 5 │
    │ b ┆ spicy ┆ 1 ┆ 2 │
    │ b ┆ mild ┆ 0 ┆ 3 │
    │ b ┆ mild ┆ 1 ┆ 0 │
    └─────────┴────────┴──────┴───────┘


    Note that channel a only has spicy flavor available, while b has both spicy and mild.

    However, the chart that is created does not update the flavors available for selection by the user based on the channel they select. This is because the flavor selector takes a fixed list of options (a required argument) that is insensitive to the transform_filter performed on the chart after channel selection.

    Is there a way for me to update the options presented by flavor based on the selection the user has made for channel? There might be a way using JupyterChart, but I am not sure if this produces an HTML chart which can is similarly interactive?

    Continue reading...

Compartilhe esta Página