将过滤器转换应用于 Altair 图,同时保留所有图例类别

Apply filter transform to Altair plot while keeping all legend categories

我正在尝试制作带有交互式图例的堆叠条形图。我希望能够 select 图例中的多个类别,这将过滤堆叠条中显示的类别。

这是我目前拥有的:

import altair as alt
import pandas as pd


df = pd.DataFrame(
    {
        "name": ["Sarah", "Sarah", "Sarah", "Sarah", "Nick", "Nick", "Nick"],
        "level": ["A", "B", "B", "C", "A", "B", "C"],
        "id": range(7),
    }
)

selection = alt.selection_multi(fields=['level'], bind='legend')

alt.Chart(df).mark_bar().encode(
    x="count(id)",
    y="name",
    color=alt.Color(
        "level",
    ),
).add_selection(
    selection
).transform_filter(
    selection
)

这会生成一个交互式图,但是当我单击图例中的一个类别时,其他类别从图例中消失。

我希望图例中的所有类别都保持可见,因此我可以 select 使用 shift 键单击多个类别(例如“B”和“C”),堆叠条形图将包括所有 selected 类别。有什么办法可以做到这一点吗?

一种直接的方法是在色阶中指定 domain

    color=alt.Color(
        "level", scale=alt.Scale(domain=['A', 'B', 'C'])
    ),

或者,如果您想以不需要域的静态规范的方式进行,您可以使用的一个技巧是在过滤后的完整图表的透明版本之后分层。例如:

base = alt.Chart(df).mark_bar().encode(
    x="count(id)",
    y="name",
    color=alt.Color(
        "level",
    ),
)

background = base.mark_bar(opacity=0)
foreground = base.add_selection(
    selection
).transform_filter(
    selection
)

background + foreground