Altair 与 Vaex

Altair with Vaex

我正在尝试使用 Vaex together with Altair,但我在将 Vaex 数据帧传递给 Altair 时遇到了一些问题。

尝试做一个简单的line chart

alt.Chart(df)\
.mark_line()\
.encode(alt.X('x'), alt.Y('y1'))

我收到一个错误提示

[the] encoding field[s] is[are] specified without a type; the type cannot be automatically inferred because the data is not specified as a pandas.DataFrame.

但如果我尝试指定它们

alt.Chart(df)\
.mark_line()\
.encode(alt.X('x:T'), alt.Y('y1:Q'))

我收到一个错误提示

altair.vegalite.v4.api.Chart->0, validating 'additionalProperties'

Additional properties are not allowed ('y1', 'x', 'y2' were unexpected)

在我看来,将 Vaex 数据框链接到 Altair 时出现了一些问题,但我不知道如何解决它...

这里是完整代码:

import altair as alt
import numpy as np
import vaex
import datetime

base = datetime.datetime.today()
dates = [base - datetime.timedelta(days=x) for x in range(10)]

y1 = np.sin(range(10))
y2 = np.cos(range(10))

df = vaex.from_arrays(x=dates, y1=y1, y2=y2)

alt.Chart(df)\
.mark_line()\
.encode(alt.X('x:T'), alt.Y('y1:Q')) #.encode(alt.X('x'), alt.Y('y1'))

Altair 与 Vaex 不兼容。最简单的方法是在 altair 图表中使用时将 Vaex 数据帧转换为 pandas;例如:

alt.Chart(df.to_pandas_df())

使用此转换几乎没有缺点:pandas 是 Altair 的硬性要求,Altair 始终会将数据序列化为 JSON,以便将其传递给 Vega-Lite.对于 Altair 可以处理的数据集大小,Vaex 提供的数据表示和序列化的效率并不是特别重要。

如果您希望它自动发生,您可以注册一个支持 vaex 的新数据转换器。这应该可以解决问题:

import altair as alt

def vaex_data_transformer(df):
  try:
    df = df.to_pandas_df()
  except AttributeError:
    pass
  return alt.data.default_data_transformer(df)

alt.data_transformers.register('vaex', vaex_data_transformer)
alt.data_transformers.enable('vaex')

启用此功能后,alt.Chart() 将在接受 pandas 数据帧的任何地方接受 vaex 数据帧。