如何基于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
相关产品推荐
相关产品推荐

