首页/新闻资讯/正文详情

Vega Zoomable Binned Plot:基于信号驱动的平移、缩放与 Stable Bins 分箱密度图实战解析

发布时间:2026/9/23 9:59:45 来源:云帆数科 栏目:资讯中心
Vega Zoomable Binned Plot:基于信号驱动的平移、缩放与 Stable Bins 分箱密度图实战解析
数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载本篇文章以 Vega 官方示例zoomable-binned-plot可缩放分箱散点图为研究对象完整拆解其 VEGA JSON 规格中点击拖拽平移、滚轮缩放、分箱聚合密度着色、Stable Bins 开关等核心机制。读者阅读本文后将能够理解 Vega 信号Signal驱动的交互式坐标域domain联动原理掌握bin、extent、aggregate等数据变换的搭配方式并能据此构建属于自己的可缩放分箱可视化。文中所有证据均来自本仓库vega的 示例规格、示例说明 及 vega-transforms 与 vega-statistics 源码。示例概述它在演示什么根据 示例说明文档 的描述这是一个支持平移与缩放的分箱聚合散点图点击并拖拽鼠标可以平移视野滚动滚轮可以缩放。它的技术演示重点有两个分箱binning如何工作——原始 2002 个二维数据点被离散化到一个个矩形分箱中以箱内点计数作为颜色编码的密度估计关闭 stable bins 选项后分箱对齐bin alignment的变化如何影响感知到的密度分布——这是本示例最微妙、也最具教学价值的一点。从仓库的 示例规格文件 可以看到整个可视化由以下部分构成信号signalsstable、hover、down、delta、anchor、zoom、xdom、ydom、size等负责全部交互状态数据datapoints原始点与density分箱聚合后的密度数据缩放scalesxscale、yscale的 domain 直接绑定到xdom/ydom信号随平移缩放实时变化标记marksrect绘制分箱矩形symbol绘制原始散点二者均设置clip: true以裁剪视野外的图形。下面按照信号 → 数据 → 缩放/轴 → 标记的脉络逐层拆解。信号系统平移与缩放的交互引擎Vega 的交互全部建立在信号Signal之上。本示例没有使用任何lex式的现成缩放组件而是手工实现了 pan/zoom 的完整数学逻辑非常适合作为学习信号级交互的范本。基础布局信号{name: margin, value: 20}, {name: xoffset, update: -(height padding.bottom)}, {name: yoffset, update: -(width padding.left)}, {name: xrange, update: [0, width]}, {name: yrange, update: [height, 0]}xoffset/yoffset用于把坐标轴从绘图区搬到画布底部和左侧配合padding留出的空间xrange/yrange定义了 x、y 缩放的比例range范围其中yrange采用[height, 0]反向区间保证数据坐标系的 y 轴向上。平移down / xcur / ycur / delta平移的核心是记录按下时的坐标域快照再根据鼠标位移增量计算新坐标域{name: down, value: null, on: [ {events: touchend, update: null}, {events: pointerdown, touchstart, update: xy()} ]}, {name: xcur, value: null, on: [ {events: pointerdown, touchstart, touchend, update: slice(xdom)} ]}, {name: ycur, value: null, on: [ {events: pointerdown, touchstart, touchend, update: slice(ydom)} ]}, {name: delta, value: [0, 0], on: [ {events: [{source: window, type: pointermove, consume: true, between: [{type: pointerdown}, {source: window, type: pointerup}]}, {type: touchmove, consume: true, filter: event.touches.length 1}], update: down ? [down[0]-x(), y()-down[1]] : [0,0]} ]}down在按下时记录鼠标/触摸点的屏幕坐标xy()在touchend时复位为nullxcur/ycur在按下时把当前xdom/ydom复制一份作为平移基准delta在从 pointerdown 到 pointerup 之间的pointermove或单指touchmove期间持续计算鼠标位移。注意between事件过滤器限定了拖拽窗口且事件带consume: true以避免与其他交互冲突。随后xdom/ydom监听delta信号把基准域按位移比例平移{name: xdom, update: slice(xext), on: [ {events: {signal: delta}, update: [xcur[0] span(xcur) * delta[0] / width, xcur[1] span(xcur) * delta[0] / width]}, ... ]}表达式span(xcur) * delta[0] / width将像素位移换算成数据域位移——鼠标向右拖delta[0]像素坐标域整体右移对应的数据量视觉上就是画布内容跟随鼠标移动。缩放anchor / zoom / dist1 / dist2缩放围绕锚点anchor展开滚轮缩放时以鼠标所在位置的数据坐标为锚点双指捏合时以两指中点对应的数据坐标为锚点{name: anchor, value: [0, 0], on: [ {events: wheel, update: [invert(xscale, x()), invert(yscale, y())]}, {events: {type: touchstart, filter: event.touches.length2}, update: [(xdom[0] xdom[1]) / 2, (ydom[0] ydom[1]) / 2]} ]}, {name: zoom, value: 1, on: [ {events: wheel!, force: true, update: pow(1.001, event.deltaY * pow(16, event.deltaMode))}, {events: {signal: dist2}, force: true, update: dist1 / dist2} ]}invert(xscale, x())通过比例尺的反函数把鼠标像素坐标还原为数据坐标这正是缩放中心不跑偏的关键zoom对滚轮使用指数形式pow(1.001, event.deltaY * ...)让缩放倍数平滑且与 deltaMode行/页/像素三种滚动模式兼容双指手势通过dist1/dist2两个信号跟踪两次touchstart/touchmove时两指间的像素距离缩放倍率取dist1 / dist2实现捏合缩放。xdom/ydom再监听zoom信号围绕锚点做线性伸缩{events: {signal: zoom}, update: [anchor[0] (xdom[0] - anchor[0]) * zoom, anchor[0] (xdom[1] - anchor[0]) * zoom]}stable 与 size 信号{name: stable, value: true, bind: {input: checkbox}}, {name: size, update: clamp(20 / span(xdom), 1, 1000)}stable是绑定到复选框checkbox的输入信号默认true用于切换稳定分箱模式下文详述size根据当前 x 方向视野跨度动态计算符号点与分箱矩形的尺寸视野越窄放大越多点越小、箱越细公式20 / span(xdom)配合clamp(..., 1, 1000)限制在合理范围内。同时hover信号通过*:pointerover/pointerout/pointerdown/pointerup事件触发hover/leave/select/release编码集管理悬停与按下时的视觉状态。数据流水线extent → bin → aggregate原始数据 pointspoints数据直接加载 data/normal-2d.json其中包含 2002 条记录每条记录有u、v两个数值字段呈二维正态分布中心密集、外围稀疏是演示密度图的理想数据。其变换只有两个extent{name: points, url: data/normal-2d.json, transform: [ {type: extent, field: u, signal: xext}, {type: extent, field: v, signal: yext} ]}extent变换计算字段的最小/最大值并存入指定信号xext、yext。其实现位于 Extent.js遍历数据pulse.visit维护min/max并跳过null/NaN值if (v ! null)若最终范围为无穷大则发出警告并将 extent 置为undefined。这里得到的xext/yext是全量数据的静态范围是稳定分箱的基准。密度数据 density分箱 聚合{name: density, source: points, transform: [ {type: extent, field: u, signal: xextf}, {type: extent, field: v, signal: yextf}, {type: bin, field: u, extent: {signal: stable ? xextf : xdom}, as: [ustart, uend], maxbins: 12, nice: {signal: stable}}, {type: bin, field: v, extent: {signal: stable ? yextf : ydom}, as: [vstart, vend], maxbins: 12, nice: {signal: stable}}, {type: aggregate, groupby: [ustart, uend, vstart, vend], as: [count]} ]}这是全示例的灵魂所在注意两处bin变换的参数extent分箱范围被绑定为stable ? xextf : xdomy 轴同理。当stable为真时分箱范围固定为全量数据的 extent当stable为假时分箱范围跟随当前视野xdom/ydom动态变化。nice同样由stable信号驱动决定是否把分箱边界凑整到美观的数值上。在 vega-transforms/src/Bin.js 中Bin.Definition定义了该变换的全部参数field必填、interval默认 true输出[bin0, bin1]区间、anchor、maxbins默认 20、base默认 10、divide默认[5, 2]用于细化步长、extent必填的二元数组、span、step、steps、minstep默认 0、nice默认 true、name与as默认[bin0, bin1]。本示例显式设置了maxbins: 12、as: [ustart, uend]以及[vstart, vend]并省略了其余参数以使用默认值。底层步长计算位于 vega-statistics/src/bin.js当未显式给出step时会根据span取值范围跨度、maxbins与base计算一个好看的步长随后在nice为真时把min向下取整、max向上取整Math.floor(min / step) * step/Math.ceil(max / step) * step使分箱边界落在整齐的刻度上。这正是stable关闭时分箱对齐变化的根源——一旦分箱范围跟随视野变化步长与边界随之重算同一批数据点会被划分到不同的箱中。最后aggregate以四个箱边界字段分组输出每箱的点数count作为密度着色的依据。为什么 stable bins 会影响感知密度理解stable的意义需要回到可视化原理分箱密度估计的结果强烈依赖分箱的对齐方式bin alignment。开启 stable默认分箱的extent固定为全量数据范围xextf/yextfnice: true使边界对齐到整数刻度如 -0.5、-0.4、...、0.5。此时无论你如何平移缩放分箱网格在数据空间中保持不动密度颜色不会因视野改变而闪烁或漂移——这正是稳定的含义。关闭 stable分箱extent改为当前视野xdom/ydomnice同时变为false。每次缩放或平移分箱网格都会随视野重新对齐。放大到局部时步长变小、网格变密但边界落在非整数位置于是同一区域在不同缩放级别下会被切成不同的箱密度颜色的分布也随之变化可能造成这里密那里疏的视觉错觉。换句话说该示例用同一个复选框向读者直观展示了分箱统计中一个经典陷阱密度图的视觉结果不仅取决于数据还取决于分箱网格的放置方式。稳定分箱保证了视野变换下密度估计的一致性代价是放大后分箱较粗非稳定分箱在放大时能获得更精细的网格但会引入对齐效应。此机制正是 docs/examples/zoomable-binned-plot.md 中所说的 how changes to the bin alignment can affect the perceived density。缩放与渲染从信号到画面动态坐标域的比例尺xscale/yscale的 domain 直接引用xdom/ydom信号因此平移缩放信号更新时比例尺随之变化所有依赖它们的标记、坐标轴自动重绘{name: xscale, zero: false, domain: {signal: xdom}, range: {signal: xrange}}, {name: yscale, zero: false, domain: {signal: ydom}, range: {signal: yrange}}zero: false表明坐标域不强制包含 0因为分箱密度图关心的是数据范围本身。颜色比例尺则取分箱计数count的线性映射使用内置的heatmap颜色方案并以 HCL 色彩空间插值interpolate: hcl以获得感知均匀的密度渐变。坐标轴与标记坐标轴位于画布外侧orient: top/right通过xoffset/yoffset信号平移到绘图区之外同时config.axis去掉了轴线domain: false、缩短刻度线tickSize: 3并使用等宽字体保证缩放过程中刻度标签清晰可读config: {axis: {domain: false, tickSize: 3, tickColor: #888, labelFont: Monaco, Courier New}}两个标记都设置了clip: true避免缩放后视野外的图形溢出rect 标记从density数据取每个箱的ustart/uend、vstart/vend映射到 x/y 位置填充色由color比例尺按count决定size信号在放大时让箱间留出间距呈现出马赛克密度网格symbol 标记叠加绘制全部原始散点黑色、fillOpacity: 0.6让读者在分箱密度的同时仍能看到底层数据分布缩放放大后点会随size信号缩小避免完全遮盖分箱颜色。如何运行与调试该示例仓库的 docs/examples 目录中每个示例都配有.md说明与.vg.json规格。该示例的运行与调试方式如下本地构建文档站点在仓库根目录安装依赖后按 docs/Gemfile 与 docs/_config.yml 的配置运行 Jekyll 站点示例页通过 _includes/example 与 _includes/embed 模板将规格内联渲染成可交互的 Vega View默认 SVG 渲染器并提供查看源码 / 导出 PNG / 导出 SVG的入口。单独加载规格直接用任意 Vega 渲染环境如vega.parsevega.View见 packages/vega加载 zoomable-binned-plot.vg.json即可获得完整的平移缩放交互无需额外代码。交互验证要点勾选/取消勾选stable bins复选框后重复平移与缩放观察分箱网格与密度颜色的变化体会分箱对齐效应鼠标滚轮缩放时观察缩放中心是否锁定在鼠标位置验证anchor的invert逻辑放大到边缘时观察size信号如何使符号点与分箱矩形缩小clamp(20 / span(xdom), 1, 1000)以及clip: true如何裁剪视野外图形。总结zoomable-binned-plot是一个小而全的 Vega 交互范例它把信号、事件、数据变换、比例尺与标记串联成一个自洽的系统交互down/xcur/ycur/delta实现拖拽平移anchor/zoom/dist1/dist2实现滚轮与捏合缩放xdom/ydom作为坐标域信号统一驱动比例尺统计extent提供静态范围binBin.js、bin.js负责离散化与对齐aggregate计算箱内计数教学价值stable复选框把分箱对齐如何影响感知密度这一统计可视化中的经典问题转化为一个可实时操作的直观演示。对于想要在自己项目中实现可缩放密度图的开发者本示例提供了完整的参考实现对于想深入理解 Vega 信号系统与bin变换的读者它则是一份可以直接对照源码研读的活教材。赞分享数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载相关推荐如何永久备份微信聊天记录WeChatExporter开源工具终极指南如何永久备份微信聊天记录WeChatExporter开源工具终极指南 你是否曾因手机丢失或系统升级而丢失珍贵的微信聊天记录那些与家人的温馨对话、工作的重要信数据可视化Vega 可缩放圆形打包图Zoomable Circle Packing实战信号驱动的钻取、补间与淡入淡出动画Vega 可缩放圆形打包图Zoomable Circle Packing实战信号驱动的钻取、补间与淡入淡出动画 本文以 Vega 官方示例 zoomabl数据可视化gVisor Systrap 平台深度解析基于 Seccomp SIGSYS 信号陷入的沙箱线程实现gVisor Systrap 平台深度解析基于 Seccomp SIGSYS 信号陷入的沙箱线程实现 本文以 gVisor 仓库中 systrap 平台说明文云原生容器运行时操作系统应用安全上一篇终极指南bililive-go 录制策略详解与文件分割最佳实践下一篇构建企业级打印代理网络vue-plugin-hiprint中转服务架构深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

2026年AI编码工具选型指南:从代码补全到调试重构的实战策略
2026年AI编码工具选型指南:从代码补全到调试重构的实战策略

1. 从"能跑就行"到"跑得漂亮":2026年开发者的效率分水岭如果你现在还在用"能跑就行"来安慰自己,那大概率已经被隔壁用AI工具链的同事甩开了一个身位。我做了十多年一线开发,从手写汇编优化到现在的AI辅助编码&… · 2026/9/23 9:59:45

Hi6421 PMIC驱动深度解析:OTP校准、I2C时序与热管理实战
Hi6421 PMIC驱动深度解析:OTP校准、I2C时序与热管理实战

简介:本资源是一份面向嵌入式Linux驱动开发工程师与电源管理技术学习者的Hi6421 PMIC核心驱动源码解析资料,聚焦移动设备与嵌入式系统中低功耗电源管理的落地实现。压缩包仅含1个C语言源文件(hi6421-pmic-core.c),大小… · 2026/9/23 9:59:45

3个步骤搞定headstrong,附完整示例避坑指南
3个步骤搞定headstrong,附完整示例避坑指南

3个步骤搞定headstrong,附完整示例避坑指南 很多刚入行的同学,对着文档里的 headstrong 语法能背得滚瓜烂熟,但真到动手搭项目时,代码一跑就报错,或者性能直接拉胯。这种“懂原理却写不出项目”的断层感,是不是让你抓狂?别急,… · 2026/9/23 9:59:38

Atlas 300V NPU部署YOLOv5:从模型转换到推理调优全指南
Atlas 300V NPU部署YOLOv5:从模型转换到推理调优全指南

1. 先弄清Atlas 300V这块卡到底是什么1.1 一块“不太像GPU”的计算卡很多刚接触昇腾生态的朋友,第一次拿到Atlas 300V的时候都会有点懵。这卡在外观上像个标准半高半长的PCIe板卡,但驱动装好之后,你在系统里看不到nvidia-smi,也不… · 2026/9/23 11:32:13

3分钟搞懂最便宜域名解析图解原理
3分钟搞懂最便宜域名解析图解原理

3分钟搞懂最便宜域名解析图解原理 盯着屏幕上一长串红色的 StackTrace,是不是感觉大脑一片空白?报错信息密密麻麻,却完全不知道从哪行代码开始查起,这种无力感太真实了。别急,今天咱们不背概念,直接上 图解原理… · 2026/9/23 11:32:13

自动化测试平台建设实战:从手工回归到pytest+Selenium+Allure体系
自动化测试平台建设实战:从手工回归到pytest+Selenium+Allure体系

上个季度,我们负责的一个核心业务系统做了一次大版本升级。手工回归花了整整三个通宵,动员了六个测试同学和四个开发,点点点的结果还是漏了一条关键链路——上线当晚就被用户反馈打爆了监控群。也就是从那次开始,我下定决心&#… · 2026/9/23 11:31:48

AI创业公司如何选择真正适配的AI-Native云平台
AI创业公司如何选择真正适配的AI-Native云平台

1. 这不是选云平台,而是选AI时代的“算力基建合伙人”最近被好几个VC朋友拉进群聊,话题高度一致:他们投的AI初创公司,上线第一个月就卡在算力调度上——模型训练跑着跑着OOM,推理服务响应延迟飙到2秒以上,G… · 2026/9/23 11:31:48

短线黑马避坑速查手册:5个致命错误与修复
短线黑马避坑速查手册:5个致命错误与修复

短线黑马避坑速查手册:5个致命错误与修复 面试被问原理答不上来,那种尴尬感比报错还难受。很多刚入行的朋友,代码写得飞起,但一被追问底层逻辑就卡壳。这往往不是能力问题,而是缺乏一套系统的 短线黑马… · 2026/9/23 11:31:48

Hermes VM 架构详解:值表示、运行时与对象模型
Hermes VM 架构详解:值表示、运行时与对象模型

Hermes VM 架构详解:值表示、运行时与对象模型 【免费下载链接】hermes A JavaScript engine optimized for running React Native. 项目地址: https://gitcode.com/gh_mirrors/hermes/hermes 本篇技术指南围绕 Hermes 引擎(一个为 React Native … · 2026/9/23 11:31:42

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码