
数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载Vega 的transforms变换是驱动数据可视化的核心处理引擎它们在数据流上执行过滤、字段计算、聚合、布局等操作把原始数据逐步加工成可绘制的视觉结构。本文以 transforms.md 为主线系统讲解变换的规范位置、五大分类基础、地理空间、布局、层级、交叉过滤及全部内置变换并结合vega-parser、vega-transforms、vega-encode、vega-crossfilter等包源码揭示其底层执行原理最后介绍如何通过 Extensibility API 注册自定义变换。读完本文你将能在 Vega 规范中正确编排数据变换管道理解transform数组与signal属性的语义并具备编写自定义变换的能力。什么是 TransformsTransforms处理数据流用于过滤数据、计算新字段或派生出新的数据流。它们通常被定义在数据定义data的transform数组中。此外不产生过滤、不生成新数据对象的变换也可以用在 mark 定义marks的transform数组中用于指定编码后的变换post-encoding transforms。从 Vega 的运行时架构看数据以流stream的方式在变换之间传递每个数据集合data set都是一条流水线transform数组中的每个变换依次消费上游脉冲pulse、产生下游脉冲。这一机制由vega-dataflow包的 Dataflow 与 Transform.js 实现每个变换都继承Transform抽象类实现transform(params, pulse)方法处理传入的数据脉冲。一个完整的变换管道示例下面的示例定义了一个新数据集先用filter变换过滤数值再计算堆叠布局例如用于堆叠条形图{ data: [ { name: table, transform: [ { type: filter, expr: datum.value 5 }, { type: stack, field: value, groupby: [category] } ] } ] }所有变换都要求一个type属性用于指定变换的名称。此外产生副作用值的变换尤其是 bin、extent 和 crossfilter可以包含signal属性用于指定一个唯一的信号名将变换的状态值绑定到该信号上。Transforms 在 Vega 规范中的位置数据变换data transform数据集合的transform数组定义了该数据集的输入数据变换管道输出即成为该数据集的值。数据集的完整属性参见 data.md其中与变换管道相关的是属性类型说明nameString必填数据集的唯一名称sourceString|String[]一个或多个源数据集的名称用于派生新数据与变换管道结合使用url / valuesString / Any外部加载或内联定义的数据源二者与source最多指定一个transformTransform[]应用于输入数据的变换数组其输出即该数据集的值从源码看parsers/data.js 负责解析数据定义它遍历data.transform数组对每个变换调用parseTransform随后调用scope.addDataPipeline构建完整的数据算子流水线。analyze函数会根据数据源形式values/url/source插入Collect、Load、Relay等算子并依据每个变换的metadatagenerates、modifies、changes、source决定是否插入额外的Collect与Sieve算子data.js。编码后变换mark transform不生成、不过滤新数据对象的变换可以被放置在 mark 定义的transform数组中直接作用于场景图项目scenegraph items而非底层数据对象。这在需要由变换设置x、y、width、height等属性来完成布局时非常有用。相关约束在 marks.md 中有明确说明。实现上parsers/mark.js 在完成编码Encode之后遍历spec.transform并做两处强制校验若变换的 metadata 带有generates或changes标志则直接报错Mark transforms should not generate new data.否则将其接入编码输出之后执行。变换的类型定义与参数解析Vega 中每个变换都通过一个Definition对象声明其类型名、metadata 与参数表例如filter的定义Filter.jsFilter.Definition { type: Filter, metadata: {changes: true}, params: [ { name: expr, type: expr, required: true } ] };解析器 parsers/transform.js 依据definition(spec.type)查找定义若找不到则报错Unrecognized transform type随后按定义中的参数表逐一解析参数支持field、expr、compare、signal、data、projection、param等参数类型并把结果封装成运行时算子。参数解析中还支持将signal引用转换为信号引用scope.signalRef从而让变换参数可以在运行时动态更新。基础变换Basic Transforms用于处理数据对象流的变换。所有基础变换的完整参数说明可分别查看 docs/docs/transforms/ 目录下的对应文档。变换说明引入版本aggregate对数据流进行分组和汇总—bin将数值离散化为均匀的箱bins—collect收集并排序数据流中的所有数据对象—countpattern统计文本字符串中模式的出现频率—cross对数据流与自身做叉积—density从概率分布中生成数值—dotbin为点图构建执行密度分箱5.7extent计算数据流上的最小值和最大值—filter使用谓词表达式过滤数据流—flatten将数组类型字段映射为数据对象每个数组元素一个对象3.1fold将选定字段折叠为key和value属性—formula使用公式表达式为数据对象扩展派生字段—identifier为数据对象分配唯一键值—kde为数值估计平滑密度5.4impute执行缺失值插补—joinaggregate用计算出的聚合值扩展数据对象—loess使用局部回归拟合平滑趋势线5.4lookup通过在其他数据流上查找键值来扩展数据对象—pivot将唯一值透视到新的聚合字段3.2project用选定字段集生成派生数据对象—quantile计算输入数据流的分位数5.7regression拟合回归模型以平滑和预测数值5.4sample对流中的数据对象进行随机采样—sequence生成包含数值序列的新数据流—timeunit将日期时间值离散化为时间单位箱5.8window在有序分组上计算包括排名与运行总计—常用基础变换深入解析filter谓词过滤filter变换依据表达式从数据流中移除对象filter.md。其唯一参数expr为必填的谓词表达式表达式求值为false时数据对象被过滤。典型用法{type: filter, expr: datum.x 10} {type: filter, expr: log(datum.y) / LN10 2}第二个例子只保留y的以 10 为底对数大于 2 的元素。从实现看Filter.js该变换内部维护一个fastmap缓存被过滤元组的 id对REM移除、ADD新增、MOD修改脉冲分别处理新增与修改时用test(t, _)重新判定从而保证流式更新时过滤结果实时正确。aggregate分组聚合aggregate变换将输入数据流分组并汇总为派生输出流可计算计数、求和、均值等描述性统计aggregate.md。核心参数属性类型说明groupbyField[]分组字段不指定则所有对象为一组fieldsField[]参与聚合运算的字段需与ops、as对齐缺省时默认使用countopsString[]聚合操作如sum、average、count缺省时默认countasString[]聚合结果输出字段名缺省时按操作与字段名自动生成如sum_fieldcrossBoolean是否输出全部 groupby 取值的完整叉积默认false为true时零计数分组也会保留dropBoolean是否丢弃空零计数分组默认true直方图等场景可设为false保留空组keyField可选的键字段用于优化分组键计算仅当该字段能唯一区分所有分组组合时使用支持的聚合操作符aggregate.md 完整列举count、valid、missing、distinct、sum、product5.10、mean、average、variance、variancep、stdev、stdevp、stderr、median、q1、q3、ci0、ci1、min、max、argmin、argmax、values。用法示例——对如下输入[ {foo: 1, bar: 1}, {foo: 1, bar: 2}, {foo: null, bar: 3} ]执行{ type: aggregate, fields: [foo, bar, bar], ops: [valid, sum, median], as: [v, s, m] }输出为[{v: 2, s: 6, m: 2}]。带groupby时则按组输出缺省ops时每组附count字段。需要留意groupby使用嵌套字段如foo.baz时输出字段名是扁平字符串后续引用需转义点号为foo\\.baz或先用project变换展开数据。从源码看Aggregate.js 的定义声明了 metadata{generates: true, changes: true}并通过AggregateOps与TupleStore维护每组的分组键与聚合单子monoid状态drop与cross参数在 Aggregate.js 处被读取用于决定是否移除空组。bin数值分箱bin变换将数值离散化为一组箱最常见的用途是构建直方图bin.md。其必填参数为field待分箱字段与extent两元素数组指定分箱范围的最小与最大值常用可选参数包括属性类型默认说明intervalBooleantrue是否同时输出起始与结束箱值false时仅输出起始向下取整箱值5.8anchorNumber最小 extent 值分箱域的锚定值必要时移动箱边界以对齐锚点maxbinsNumber20最大箱数实际往往更少因边界取整齐数值baseNumber10自动分箱确定的数制基数stepNumber—精确步长提供后maxbins等选项被忽略stepsNumber[]—可选的步长集合spanNumberextent[1]-extent[0]生成箱边界的值跨度可在保留整体 extent 的前提下为缩放区域自定义步长5.6minstepNumber0最小允许步长divideNumber[][5, 2]允许的步长细分基数 10 时可考虑除以 5 或 2niceBooleantrue是否让箱边界采用人类友好的取值如 10 的倍数signalString—将计算得到的分箱规格含start、stop、step的对象绑定到指定信号asString[][bin0, bin1]起始与结束箱值的输出字段名用法示例将amount字段分入 0 到 10 之间的 5 个箱{type: bin, field: amount, extent: [0, 10], maxbins: 5}对输入3.7、6.2、5.9、8输出bin0/bin1分别为[2,4]、[6,8]、[4,6]、[8,10]bin.md 有完整输入输出对照。源码实现位于 Bin.js其中maxbins、base、divide、nice等默认值均与文档一致分箱函数本身由vega-statistics的bin提供并带有1e-14的浮点误差补偿Bin.js上限值采用start step * (1 (v - start) / step)公式计算以保证更好的浮点一致性。bin变换还能通过signal属性把分箱规格start、stop、step暴露给信号系统供后续标度等其他部分复用。formula公式派生字段formula变换为每个数据元组执行一个函数并把结果保存为新字段Formula.js。参数expr必填公式表达式与as必填结果字段名可选initonly布尔默认false表示公式仅应用于新增元组、不响应修改。实现上Formula.js当参数被修改时执行reflow(true)重新计算全量initonly模式下只访问pulse.ADD否则根据字段依赖选择ADD_MOD或ADD并通过pulse.modifies(as)声明输出字段。sequence序列生成sequence变换生成一段数值序列作为新的数据流不依赖输入数据metadata 为generates、changes。参数start必填、stop必填不含、step默认 1、as默认data。实现位于 Sequence.js内部使用d3-array的range函数生成数值并为每个值生成{ [as]: v }形式的元组。extent极值计算extent变换计算某个字段的最小与最大值Extent.js参数仅field必填。它是一个典型的副作用变换状态值[min, max]可通过signal属性暴露给信号系统这也是主文档特别提及extent可用signal的原因。实现上它遍历SOURCE或ADD脉冲并用toNumber比较更新极值当结果为无穷大时会发出Infinite extent for field ...警告并将值重置为undefinedExtent.js。project字段投影project变换执行关系投影把源元组的选定字段复制到一组新的派生元组Project.js。参数fields要投影的字段数组与as对应的输出字段名缺省沿用字段名。它通过维护源元组 id 到派生元组的映射lut将REM/ADD/MOD事件一一映射到派生数据metadata 为generates、changes。collect收集排序collect变换收集通过该算子的所有数据元组Collect.js可选sort比较器进行排序。它的 metadata 为source: true因此常被解析器自动插入到数据管道中作为源算子见 parsers/data.js内部用SortedList维护有序集合。地理与空间变换Geographic and Spatial Transforms用于建模空间数据、制图投影与地理参考线的变换。对应源码主要位于vega-geo包packages/vega-geo/src。变换说明引入版本contour已弃用Deprecated。使用离散层级建模空间分布—geojson将地理数据整合为 GeoJSON 要素集合—geopath将 GeoJSON 要素映射为 SVG 路径字符串—geopoint将经度纬度坐标映射为x, y点—geoshape将 GeoJSON 要素映射为用于程序化绘制的 shape 实例—graticule为制图地图生成参考经纬网格—heatmap为栅格网格数据生成热力图图像5.8isocontour为栅格网格数据生成等值线5.8kde2d估计二维密度并输出栅格网格5.8其中geopath、geopoint、geoshape、graticule等通常与投影projections配合使用通过projection参数引用规范中定义的投影名称把经纬度坐标换算为屏幕坐标。heatmap、isocontour、kde2d三个 5.8 版本引入的变换面向栅格raster grid数据kde2d与基础变换中的kde一维密度估计形成对应关系其输出可作为heatmap/isocontour的输入。布局变换Layout Transforms用于计算空间坐标以实现各类布局的变换。变换说明引入版本force通过物理模拟计算力导向布局—label计算文本位置与不透明度以标注图表5.16linkpath为节点元素之间的视觉连线布线—pie为饼图与环形图计算角度布局—stack为成组数值计算堆叠布局—voronoi为一组点计算 Voronoi 图—wordcloud计算文本字符串的词云布局—stack堆叠布局stack变换通过堆叠成组数值计算布局最常见的用途是创建堆叠条形图与流图stream graphstack.md。它会向每个数据对象写入两个属性表示堆叠的起始与结束值。参数如下属性类型说明fieldField决定堆叠高度的数据字段groupbyField[]将数据划分为独立堆叠的分组字段数组sortCompare每个堆叠内部值的排序标准offsetString基线偏移zero默认从 0 开始堆叠、center居中堆叠、normalize计算每个堆叠点的百分比输出值在 [0,1] 范围asString[]起始与结束堆叠值的输出字段默认[y0, y1]用法示例——按x分组、以y为堆叠高度、按v降序排列结果写入y0/y1{ type: stack, groupby: [x], field: y, sort: {field: v, order: descending} }第二个示例演示多条件排序与自定义输出字段{ type: stack, groupby: [category], field: x, sort: { field: [u, v], order: [ascending, descending] }, as: [x0, x1] }实现上stack变换位于vega-encode包Stack.js其Definition中offset的枚举值正是zero/center/normalizeas的默认值为[y0, y1]。运行时分三步先用partition按groupby分组并求和排序再根据offset选择stackZero、stackCenter或stackNormalize三个布局函数之一计算每个分组的起止值Stack.js。它的 metadata 为{modifies: true}——只修改已有元组、不生成新对象因此完全符合 mark 后编码变换的约束可安全用于 mark 的transform数组。层级变换Hierarchy Transforms用于处理层级树数据并执行树布局的变换。相关实现位于vega-hierarchy包packages/vega-hierarchy/src。变换说明nest通过按字段值分组来生成树结构stratify使用显式键值生成树结构treelinks为树结构生成连线数据对象pack基于圆形包络的树布局圆填充partition基于节点空间相邻的树布局旭日图tree用于节点-连线图的树布局treemap基于递归矩形细分的树布局矩形树图这组变换通常成对使用先用nest按字段层级分组或stratify按显式父子键把扁平数据构造成树再用pack、partition、tree、treemap之一计算节点坐标。treelinks则在布局完成后从树结构生成节点之间的连线数据供line或path等 mark 绘制。仓库的 examples 目录中提供了大量可运行的示例规范例如 tree-layout.vg.json、treemap.vg.json、circle-packing.vg.json 与 sunburst.vg.json分别对应tree、treemap、pack与partition的实际使用。交叉过滤变换Cross-Filter Transforms用于支持多维数据快速增量过滤的变换相关实现位于独立的vega-crossfilter包packages/vega-crossfilter/src。变换说明crossfilter为多个维度的查询维护过滤掩码filter maskresolvefilter解析 crossfilter 输出以生成过滤后的数据流crossfilter变换在内部为每个维度建立排序索引SortedIndex与维度对象Dimension并通过位图Bitmaps维护当前与上一轮的过滤掩码CrossFilter.js从而在数据量很大时实现接近常数级的增量过滤——这正是crossfilter-flights等示例crossfilter-flights.vg.json能够流畅联动刷选的基础。resolvefilter变换则消费这些位图掩码依据ignore位掩码决定哪些维度的过滤条件参与筛选并在只有一个维度变化时采用专门优化路径避免全量重算ResolveFilter.js。主文档提到crossfilter是可以通过signal属性暴露状态值的变换之一在规范中crossfilter通常配合signal输出维度过滤信号而resolvefilter则把这些过滤结果解析为下游数据集的实际增删改事件。自定义变换Custom Transforms除了上述内置变换Vega 还允许通过其Extensibility API添加自定义变换。详细说明见 API 文档的 Transformations 一节。自定义变换的注册流程可以概括为定义 → 注册 → 解析 → 运行四个环节定义编写一个继承自vega-dataflow中Transform的构造函数实现transform(params, pulse)方法并挂载一个Definition对象声明类型名、metadata 与参数表参考 Aggregate.js 与 Filter.js 的写法。注册通过vega.transforms(name, transform)之类的注册函数把构造函数加入变换注册表——解析器 parsers/transform.js 正是调用definition(spec.type)从注册表中查找定义vega-dataflow的 register.js 实现了该注册表的按类型查找逻辑。解析Vega 解析器按Definition中的参数表把规范里的 JSON 参数转换为运行时参数parsers/transform.js。运行运行时上下文Context.transform(spec, type)从注册表中取出构造器实例化算子并接入数据流vega-runtime/src/context.js。自定义变换的 metadata 标志source、generates、modifies、changes、nomod会直接影响解析器对数据管道的编排见前文 parsers/data.js 对 metadata 的扫描因此在定义变换时务必准确声明。变换的执行原理与管道编排理解变换管道可以把一条数据流看作一串算子operator的链式结构。以数据定义{ name: table, transform: [...] }为例parsers/data.js 的analyze函数会根据数据来源values/url/source确定起始算子内联值或 URL 加载通常以Collect含$ingest/$request/$format参数为源url或format含信号时改用动态Load算子data.js依次遍历规范中的变换必要时在变换前插入Collect算子以保证下游可重放数据data.js若数据来自其他数据集source用Relay算子合并多路输入并根据上游是否有修改性变换决定是否派生derive新元组data.js在管道末端追加Sieve算子以标记数据集的最终输出。运行时每个变换算子继承 Transform.js 的run/evaluate机制run通过脉冲时间戳pulse.stamp判断是否需要执行evaluate用 Parameters.js 封装的参数对象调用transform(params, pulse)参数修改记录modified标记则驱动各变换的增量更新策略——这也是交互式过滤、刷选时 Vega 能只重算受影响部分的原因。总结Vega 的变换体系按职责清晰地划分为五大类基础变换负责数据流的分组聚合、过滤、字段派生与序列生成地理空间变换处理 GeoJSON 与投影制图布局变换计算堆叠、饼图、力导向、词云等坐标层级变换构建并布局树形数据交叉过滤变换为多维联动刷选提供高性能增量过滤。所有变换共用一套类型定义 参数表 metadata的声明式机制既保证了规范 JSON 的可读性也让解析器能够自动编排数据管道、运行时能够增量更新。若内置能力不足还可以通过 Extensibility API 编写自定义变换并注册进解析器与运行时。想深入某个具体变换可直接查阅 docs/docs/transforms/ 目录下对应的参数文档并在 docs/examples/ 中找到大量可运行的完整示例。赞分享数据可视化【免费下载链接】vegaA visualization grammar.项目地址https://gitcode.com/gh_mirrors/ve/vega点击查看免费下载相关推荐MMDetection 数据变换Data Transforms完全指南从数据管线到自定义增强MMDetection 数据变换Data Transforms完全指南从数据管线到自定义增强 导读 数据变换transforms是 MMDetecti人工智能计算机视觉深度学习模型评测Oh My CV革命性浏览器端Markdown简历生成器无需安装本地优先的简历制作新体验Oh My CV革命性浏览器端Markdown简历生成器无需安装本地优先的简历制作新体验 在数字化求职时代一份专业的简历是成功求职的第一步。Oh Mymmsegmentation 自定义数据变换Data Transform完整指南基于 BaseTransform 与 TRANSFORMS 注册器mmsegmentation 自定义数据变换Data Transform完整指南基于 BaseTransform 与 TRANSFORMS 注册器 导读人工智能深度学习计算机视觉创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考