独立于过滤器绘制 DataFrame 的一部分

Plot one part of a DataFrame independent of filter

我想根据滑块的值绘制我的数据框的一部分(即滑块过滤在特定列中具有匹配值的行)。某些行在用于过滤的列中缺少值。我希望这些行始终显示在图中 - 无论滑块如何。

这里有一些代码用于说明。用于筛选的列在此示例中称为 parameter

In [1]:  import altair as alt
         import pandas as pd

In [2]:  df_with_parameter_col = pd.DataFrame(
             {
                 "x": [1, 1],
                 "y": [2, 3],
                 "parameter": [2, 3]
             }
         )

         df_without_parameter_col = pd.DataFrame(
             {
                 "x": [1],
                 "y": [1]
             }
         )

In [3]:  df = pd.concat([df_with_parameter_col,
                         df_without_parameter_col])
         df
Out [3]:        x   y   parameter
            0   1   2   2.0
            1   1   3   3.0
            0   1   1   NaN

In [4]:  slider_parameter = alt.binding_range(min=2, max=3, step=1, name="Parameter ")

         select_parameter = alt.selection_single(
             fields=["parameter"],
             bind={"parameter": slider_parameter},
             init={"parameter": 2},
             name="Slider"
         )

         chart = alt.Chart(df).mark_point().encode(
             y="y",
             x="x",
         ).add_selection(
             select_parameter
         ).transform_filter(
             select_parameter
         )

parameter 列中缺失值的行中的数据从不绘制。解决此问题的一种方法是为滑块的每个可能值 复制此行 ,并将 NaN 更改为可以匹配滑块值的值。但是,这在内存方面会非常浪费。有没有更好的解决方案?

您可以使用 vega expression 语法使用稍微复杂一些的过滤语句来执行此操作:

slider_parameter = alt.binding_range(min=2, max=3, step=1, name="Parameter ")

select_parameter = alt.selection_single(
    fields=["parameter"],
    bind={"parameter": slider_parameter},
    init={"parameter": 2},
    name="Slider"  # Note: if this is changed, change the name below as well.
)

alt.Chart(df).mark_point().encode(
    y="y",
    x="x",
).add_selection(
    select_parameter
).transform_filter(
    # Note: "Slider" here matches the `name` specified for the selection.
    # Its attributes are drawn from the `fields` specified for the selection.
    "!isValid(datum.parameter) || (datum.parameter == Slider.parameter)"
)