首页 > 解决方案 > 是否可以使用具有时间编码类型的 altair 变换过滤器?

问题描述

Altair 变换过滤器似乎不适用于我的时间编码。

我正在尝试构建一个单一的时间序列折线图,在悬停时,选择了一个日期,并在旁边的另一个条形图中显示了按类别划分的细分,但是,过滤似乎不起作用。

我的选择器是

nearest = alt.selection(type='single', nearest=True, on='mouseover',
                        fields=['date'], empty='none')

我的过滤器是

transform_filter(alt.datum.date == nearest.date)

上面有什么明显的错误吗?

这也是一个独立的示例,说明了虚拟数据的问题:

import altair as alt
import pandas as pd
import numpy as np

dates = pd.date_range('2020-01-01', '2020-06-01', freq='bm')

df1 = pd.Series(np.random.rand(len(dates)), index=dates).reset_index()
df1.columns = ['date', 'value']

df2 = pd.DataFrame({'Cat A': [1,2,3,4,5], 'Cat B': [4,5,6,7,8]}, index=dates).stack().reset_index()
df2.columns = ['date', 'category', 'category_value']

nearest = alt.selection(type='single', nearest=True, on='mouseover',
                        fields=['date'], empty='none')

c1 = alt.Chart(df1).mark_line().encode(
  x='date:T',
  y='value:Q',
)

selectors = alt.Chart(df1).mark_point().encode(
    x='date:T',
    y='value:Q',
    opacity=alt.condition(nearest, alt.value(1), alt.value(0))
).add_selection(
    nearest
)


c2 = alt.Chart(df2).mark_bar().encode(
x='category',
y='category_value').transform_filter(alt.datum.date == nearest.date)

(c1 + selectors) | c2 

标签: pythonaltairvega-lite

解决方案


这里有两个问题:

  • 您正在将原始日期字符串与解析的时间戳进行比较。您需要调用toDate()原始数据来纠正此问题。
  • python在表达式中==转换为 javascript ;===因为nearest.date返回一个列表,我们需要使用限制较少的==运算符。这不能通过 获得alt.expr,因此我们可以直接传递一个 vega 表达式字符串。

如果你使用这个过滤器,它应该会处理这些问题:

.transform_filter(
    f"toDate(datum.date) == {nearest.date}"
)

推荐阅读