Altair图表实现:双选择器单激活显示各自选区、双激活仅显示交集
问题根因
原有代码的颜色筛选条件存在逻辑缺陷:
- 最初编写的
(alex & ~morgan) | (~alex & morgan) | (alex & morgan)化简后等价于alex | morgan,只要元素落在任意一个选区内就会被上色,导致两个选择器同时激活时会展示两个选区的并集,不符合取交集的要求。 - 原逻辑未区分选择器是否处于激活状态,无法在双激活场景下自动切换为交集判断规则。
实现方案
利用Vega-Lite 内置的selection长度判断能力,通过length(选择器名称)获取指定选择器的有效选区大小(返回值为0代表未生成有效选区,大于0代表已激活),分三层实现判断逻辑:
- 仅alex选择器激活时:展示alex选区命中的元素
- 仅morgan选择器激活时:展示morgan选区命中的元素
- 两个选择器同时激活时:仅展示同时落在两个选区内的交集元素
修正后可运行代码
import altair as alt from vega_datasets import data cars = data.cars.url # 保留原有两个间隔选择器的配置 alex = alt.selection_interval( on="[mousedown[event.altKey], mouseup] > mousemove", name='alex', resolve='intersect' ) morgan = alt.selection_interval( on="[mousedown[event.shiftKey], mouseup] > mousemove", mark=alt.BrushConfig(fill="#fdbb84", fillOpacity=0.5, stroke="#e34a33"), name='morgan', resolve='intersect' ) alt.Chart(cars).mark_rect().encode( x='Cylinders:O', y='Origin:O', # 替换原有的错误条件为分场景判断逻辑 color=alt.condition( # 分场景判断(原生Vega-Lite表达式) "(alex && length(morgan) == 0) || (morgan && length(alex) == 0) || (alex && morgan && length(alex) > 0 && length(morgan) > 0)", 'count()', alt.ColorValue("grey") ) ).add_selection( alex, morgan ).properties( width=300, height=180 )
效果说明
- 单激活任意一个选择器时,图表正常展示对应选区的统计结果
- 两个选择器同时绘制选区时,仅展示两个选区的重叠交集部分的统计结果
- 两个选择器都未激活时,所有区块显示为灰色,符合预期
内容的提问来源于stack exchange,提问作者Krezz
相关产品推荐
相关产品推荐

