使用selection_interval时出现异常渲染行为求助
Altair甘特图迷你图缩放Y轴时的渲染异常问题
我在Jupyter Notebook中用以下代码生成设备调度甘特图,设计思路是通过右侧的迷你图(minimap)来缩放/平移主图的Y轴。但在迷你图中用鼠标缩放或平移时,主图顶部出现奇怪的渲染异常——选中区域上方的所有条形似乎都被渲染在主图顶部。想知道这是代码问题还是渲染bug?
代码实现
import altair as alt import pandas as pd events = pd.DataFrame( [ {"event": "Task A", "equipment": "SK-101", "start": 10.2, "finish": 11.3}, {"event": "Task B", "equipment": "SK-102", "start": 6.5, "finish": 10.2}, {"event": "Task C", "equipment": "SK-103", "start": 3.3, "finish": 11.3}, {"event": "Task D", "equipment": "SK-104", "start": 4.7, "finish": 5.5}, {"event": "Task E", "equipment": "SK-105", "start": 13.0, "finish": 13.2}, {"event": "Task F", "equipment": "SK-106", "start": 1.1, "finish": 7.9}, {"event": "Task G", "equipment": "SK-107", "start": 7.4, "finish": 10.0}, {"event": "Task H", "equipment": "SK-108", "start": 6.6, "finish": 7.6}, {"event": "Task I", "equipment": "SK-109", "start": 8.5, "finish": 16.7}, {"event": "Task J", "equipment": "SK-110", "start": 9.0, "finish": 12.2}, {"event": "Task K", "equipment": "SK-111", "start": 10.2, "finish": 17.3}, {"event": "Task L", "equipment": "SK-112", "start": 6.1, "finish": 9.5}, {"event": "Task M", "equipment": "SK-113", "start": 5.4, "finish": 5.8}, {"event": "Task N", "equipment": "SK-114", "start": 2.2, "finish": 8.3}, {"event": "Task O", "equipment": "SK-115", "start": 9.3, "finish": 10.6}, {"event": "Task P", "equipment": "SK-116", "start": 3.9, "finish": 12.5}, {"event": "Task Q", "equipment": "SK-117", "start": 11.1, "finish": 16.6}, {"event": "Task R", "equipment": "SK-118", "start": 14.4, "finish": 18.4}, {"event": "Task S", "equipment": "SK-119", "start": 19.2, "finish": 19.9}, {"event": "Task T", "equipment": "SK-120", "start": 13.8, "finish": 16.7}, {"event": "Task U", "equipment": "SK-102", "start": 12.0, "finish": 13.0}, {"event": "Task V", "equipment": "SK-106", "start": 10.2, "finish": 17.3}, {"event": "Task W", "equipment": "SK-108", "start": 12.8, "finish": 14.9}, {"event": "Task X", "equipment": "SK-110", "start": 12.6, "finish": 18.9}, {"event": "Task Y", "equipment": "SK-112", "start": 13.3, "finish": 18.3}, {"event": "Task Z", "equipment": "SK-114", "start": 8.6, "finish": 19.2}, ] ) brush = alt.selection_interval(encodings=["y"]) minimap = ( alt.Chart(events) .mark_bar() .add_params(brush) .encode( x=alt.X("start:Q", title="", axis=alt.Axis(labels=False, tickSize=0)), x2="finish", y=alt.Y("equipment:N", title="", axis=alt.Axis(labels=False, tickSize=0)), color=alt.condition(brush, "event", alt.value("lightgray")), ) .properties( width=100, height=400, title="minimap" ) ) detail = ( alt.Chart(events) .mark_bar() .encode( x=alt.X("start:Q", title="time (hr)"), x2="finish", y=alt.Y("equipment:N").scale(domain={"param": brush.name, "encoding": "y"}), color="event", ) .properties(width=600, height=400, title="Equipment Schedule") ) detail | minimap
状态截图
- 未缩放状态:

- 缩放后状态:

问题原因与修复方案
这是代码实现方式的问题,并非渲染bug。你原本通过Y轴的scale domain绑定迷你图选择器,这种方式只是限制了轴的显示范围,但未过滤数据,未被选中的设备会被视为缺失值,默认渲染在轴的顶部。
正确的做法是给主图添加数据过滤,只保留选中的设备:
修改后的detail图表代码:
detail = ( alt.Chart(events) .mark_bar() .transform_filter(brush) # 过滤选中的设备数据 .encode( x=alt.X("start:Q", title="time (hr)"), x2="finish", y=alt.Y("equipment:N"), color="event", ) .properties(width=600, height=400, title="Equipment Schedule") )
这样修改后,主图只会渲染迷你图中选中的设备,彻底解决异常堆叠问题。
内容的提问来源于stack exchange,提问作者multipitch
相关产品推荐
相关产品推荐

