You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Altair筛选图表实时计算选中序列的差值?

解决方案:实时计算选中序列的差值折线图

核心思路是将两个选中序列的时间序列数据通过transform_lookup关联到同一行,然后计算差值并绘制折线图。以下是完整可运行代码:

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

# 生成模拟时间序列数据
ex_ts = pd.DataFrame(
    np.random.random((10, 5)),
    columns=['a', 'b', 'c', 'd', 'e'],
    index=(
        pd.date_range(
            start=pd.to_datetime('today')-pd.Timedelta(9, unit='D'), 
            end=pd.to_datetime('today')).strftime('%Y-%m-%d')
        )
)

# 转换为长格式,用于折线图绘制
ex_ts_long = ex_ts.stack().reset_index().set_axis(
    ['date', 'category', 'value'],
    axis=1
)

# 生成热图数据:计算最新观测值的两两差值
def get_last_diff(i):
    return ex_ts.sub(ex_ts.iloc[:,i], axis=0).iloc[-1,:]

ex_z = pd.concat(
    [get_last_diff(i) for i in np.arange(0, 5)],
    axis=1
).set_axis(
    ex_ts.columns,
    axis=1).stack().reset_index().set_axis(
    ['x', 'y', 'diff'],
    axis=1
).round(2)

# 定义点选交互,设置empty='none'确保必须选中两个序列才触发后续计算
select_x = alt.selection_point(fields=['x'], name='select_x', empty='none')
select_y = alt.selection_point(fields=['y'], name='select_y', empty='none')

# 热图绘制
base_hmap = alt.Chart(ex_z).encode(
    x='x',
    y='y',
    color='diff'
).add_params(select_x, select_y).properties(width=500, height=500)

hmap = base_hmap.mark_rect()
text = base_hmap.mark_text(fontWeight='bold').encode(
    text='diff',
    color=alt.value('red')
)
hmap_chart = hmap + text

# 展示选中序列的原始折线图
line_selected = alt.Chart(ex_ts_long).mark_line().encode(
    x='date:T',
    y='value:Q',
    color='category:N'
).transform_filter(select_x | select_y)

# 计算并绘制选中序列的差值折线图
# 第一步:提取选中x序列的日期-值数据
x_data = alt.Chart(ex_ts_long).transform_filter(select_x).transform_aggregate(
    x_value='sum(value)',  # sum仅用于聚合单值,每个日期对应选中序列的唯一值
    groupby=['date']
).rename(columns={'x_value': 'value_x'}).mark_line(opacity=0)  # 不显示原始线

# 第二步:提取选中y序列数据,关联x序列数据后计算差值
diff_line = alt.Chart(ex_ts_long).transform_filter(select_y).transform_aggregate(
    y_value='sum(value)',
    groupby=['date']
).transform_lookup(
    lookup='date',
    from_=alt.LookupData(x_data, 'date', ['value_x'])
).transform_calculate(
    diff = 'datum.y_value - datum.value_x'
).mark_line(color='orange', strokeWidth=2).encode(
    x='date:T',
    y='diff:Q',
    tooltip=[alt.Tooltip('date:T'), alt.Tooltip('diff:Q', format='.2f')]
).properties(title='选中序列的差值')

# 组合所有图表
final_chart = alt.vconcat(
    hmap_chart,
    alt.hconcat(line_selected, diff_line).properties(width=400, height=300)
)

final_chart

关键细节说明

  • 数据关联:通过transform_lookup将两个选中序列的同日期数据匹配到同一行,为差值计算提供数据基础。
  • 交互约束:设置empty='none',确保只有同时选中两个序列时,差值折线图才会显示。
  • 聚合处理:使用transform_aggregate保证每个日期仅保留选中序列的单个值,避免数据重复导致计算错误。

内容的提问来源于stack exchange,提问作者mknifton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 03:23:15