Altair 的选择和 transform_filter 通过 binding_range 滑块的日期时间值似乎不适用于相等条件或选择器本身

Altair's selection and transform_filter via binding_range slider for datetime values doesn't seem to work with equality condition or selector itself

我想将范围滑块与日期时间值绑定,以仅过滤特定日期数据的图表。使用 stocks 数据,我想要做的是让 x 轴显示公司,y 轴显示用户通过范围滑块选择的特定日期的股票价格.

基于 this answer and this issue 的输入,我有以下代码显示了一些东西 当滑块在一个特定值之后移动时(transform_filter 中的不等式条件),但其余为空。 奇怪的是,如果我有不等运算符,那么至少它会显示一些东西,但是 当它的 ==.

时,一切都是空的
import altair as alt
from vega_datasets import data

source = data.stocks()

def timestamp(t):
  return pd.to_datetime(t).timestamp()

slider = alt.binding_range(step=86400, min=timestamp(min(source['date'])), max=timestamp(max(source['date']))) #86400 is the difference b/w consequetive days

select_date = alt.selection_single(fields=['date'], bind=slider, init={'date': timestamp(min(source['date']))})

alt.Chart(source).mark_bar().encode(
    x='symbol',
    y='price',
).add_selection(select_date).transform_filter(alt.datum.date == select_date.date)

由于输出为空,我倾向于得出结论是 transform_filter 导致了问题,但我已经处理了 6 个多小时,并尝试了使用 alt.expr.toDate 和其他转换,但我无法让它工作。

还尝试了 transform_filter(select_date.date)transform_filter(date) 以及其他方法,但没有什么效果。

预期输出是,当用户拖动滑块时,条的高度发生变化(由于数据在日期被过滤).

任何帮助将不胜感激。

这里有几个问题:

  • 在Vega-Lite中,时间戳以毫秒表示,而不是秒
  • 您正在根据数字时间戳和日期的字符串表示形式之间的相等性进行过滤。
  • 即使您解析过滤器表达式中的日期,Python 日期解析和 Javascript 日期解析的行为也不同,结果通常不会匹配。即使在 javascript 内,日期解析行为也会因浏览器而异;所有这些都意味着过滤 Python 和 Javascript 时间戳的相等性通常是有问题的
  • 您使用的数据有每月时间戳,因此滑块步骤应考虑到这一点

牢记所有这些,最好的方法可能是调整滑块值并过滤匹配的年份和月份,而不是试图在确切的时间戳中实现相等。结果如下所示:

import altair as alt
from vega_datasets import data
import pandas as pd

source = data.stocks()

def timestamp(t):
  return pd.to_datetime(t).timestamp() * 1000

slider = alt.binding_range(
    step=30 * 24 * 60 * 60 * 1000, # 30 days in milliseconds
    min=timestamp(min(source['date'])),
    max=timestamp(max(source['date'])))

select_date = alt.selection_single(
    fields=['date'],
    bind=slider,
    init={'date': timestamp(min(source['date']))},
    name='slider')

alt.Chart(source).mark_bar().encode(
    x='symbol',
    y='price',
).add_selection(select_date).transform_filter(
    "(year(datum.date) == year(slider.date[0])) && "
    "(month(datum.date) == month(slider.date[0]))"
)

您可以在此处查看结果:vega editor