Loading...
quantize 是一种离散化比例尺,它将连续的数据域(domain)划分为若干个等宽的区间,并将这些区间映射到离散的值域(range)中。它属于分段比例尺的一种,主要用于将连续数据离散化处理。
与 threshold 比例尺类似,quantize 也是将连续数据映射为离散值,但不同的是:
与 quantile 比例尺的区别在于:
quantize 比例尺的工作原理是:
例如,对于数据域 [0, 100] 和值域 ['小', '中', '大']:
quantize 比例尺适用于以下场景:
chart.options({type: 'cell',data: salaryData,encode: {color: 'salary',},scale: {color: {type: 'quantize',range: ['#eee', 'pink', 'red'], // 将数据分为三组,每组对应一种颜色},},});
quantize 比例尺主要负责将连续的数据域映射到离散的值域。以下是 quantize 比例尺的配置选项:
属性 | 描述 | 类型 | 默认值 | 必选 |
---|---|---|---|---|
type | 比例尺类型,需为 'quantize' | string | 无 | ✓ |
domain | 设置数据的定义域范围 | number[] | [0, 1] | |
range | 设置数据映射的值域范围 | any[] | [0.5] | |
unknown | 对于 undefined , NaN ,null 空值,返回的数据 | any | undefined | |
tickCount | 设置推荐的 tick 生成数量,tickCount 只是建议值,不会完全按照这个值产生 tick | number | 5 | |
tickMethod | 设置生成 tick 的方法,常用于自定义 tick | (min: number, max: number, count: number) => number[] | wilkinson-extended | |
nice | 扩展 domain 范围,让输出的 tick 展示得更加友好 | boolean | false |
下面是一个使用 quantize 比例尺创建热力图的示例,将薪资数据按照数值大小分为三个等宽区间,并映射为不同的颜色:
import { Chart } from '@antv/g2';// 创建一个容器元素const container = document.createElement('div');const chart = new Chart({container: 'container',container,height: 340,});chart.options({type: 'cell',data: {type: 'fetch',value:'https://gw.alipayobjects.com/os/bmw-prod/89c20fe8-0c6f-46c8-b36b-4cb653dba8ed.json',transform: [{ type: 'map', callback: (d) => ({ salary: d }) }],},scale: {color: {type: 'quantize',range: ['#eee', 'pink', 'red'], // 将数据分为三组,对应三种颜色},},legend: {color: {length: 400,labelFormatter: '.0s', // 格式化图例标签,使用缩写形式(如 10K 代替 10000)},},encode: {y: (_, i) => (i % 5) + 1, // 设置单元格的行位置x: (_, i) => ((i / 5) | 0) + 1, // 设置单元格的列位置color: 'salary', // 将薪资数据映射到颜色通道},style: {stroke: '#000', // 设置单元格边框颜色inset: 2, // 设置单元格内边距},animate: {enter: { type: 'fadeIn' }, // 添加淡入动画效果},});chart.render();
在上面的示例中:
.0s
格式化器,将大数字显示为更易读的形式(如 10K)比例尺类型 | 数据类型 | 分段方式 | 适用场景 |
---|---|---|---|
quantize | 连续数值 | 等宽分段 | 数据分布均匀,需要按数值范围分组 |
quantile | 连续数值 | 等频分段 | 数据分布不均,需要每组数据量相等 |
threshold | 连续数值 | 自定义阈值 | 需要按特定阈值分组(如及格线) |
下面的示例展示了 quantize 和 quantile 比例尺在处理偏斜数据时的区别:
import { Chart } from '@antv/g2';// 创建一个偏斜分布的数据集,使用整数值const generateSkewedData = () => {const data = [];// 大部分数据集中在低值区域for (let i = 0; i < 60; i++) {// 使用整数值,避免小数点导致的重叠data.push({ value: Math.floor(5 + Math.random() * 25), type: '偏斜数据' });}// 少量数据分布在高值区域,更加分散for (let i = 0; i < 15; i++) {data.push({ value: Math.floor(60 + Math.random() * 20), type: '偏斜数据' });}// 添加一些中间值,使分布更加明显for (let i = 0; i < 10; i++) {data.push({ value: Math.floor(40 + Math.random() * 15), type: '偏斜数据' });}return data;};const data = generateSkewedData();// 创建两个图表进行对比const container = document.createElement('div');container.style.display = 'flex';container.style.flexDirection = 'column';container.style.gap = '40px'; // 增加间距container.style.width = '100%';container.style.maxWidth = '800px';container.style.margin = '0 auto'; // 居中显示// 添加标题const title = document.createElement('h3');title.textContent = 'quantize 与 quantile 比例尺对比';title.style.textAlign = 'center';title.style.marginBottom = '10px';container.appendChild(title);// quantize 比例尺图表const chart1Container = document.createElement('div');chart1Container.style.width = '100%';chart1Container.style.height = '220px'; // 增加高度container.appendChild(chart1Container);const chart1 = new Chart({container: 'container',container: chart1Container,height: 220,autoFit: true, // 自动适应容器大小padding: [50, 100, 70, 100], // 增加内边距,给标签留出更多空间});chart1.options({type: 'point',data,title: {text: 'quantize 比例尺(等宽分段)',style: {fontSize: 14,fontWeight: 'bold',},},scale: {color: {type: 'quantize',range: ['#e8f4f8', '#a8d5e5', '#4ba3c3', '#0a6c93'], // 4个颜色分段},value: {nice: true,tickCount: 5, // 减少刻度数量formatter: '.0f', // 使用G2内置的格式化器显示整数},},encode: {x: 'value',y: 'type',color: 'value',shape: 'circle',size: 8,},style: {fillOpacity: 0.8,stroke: '#fff',lineWidth: 1,},legend: {color: {position: 'top',length: 200, // 设置图例长度labelFormatter: '.0f', // 使用G2内置的格式化器显示整数},},axis: {y: false,x: {labelSpacing: 10, // 增加标签间距labelFormatter: '.0f', // 使用G2内置的格式化器显示整数tickCount: 5, // 减少刻度数量},},});chart1.render();// quantile 比例尺图表const chart2Container = document.createElement('div');chart2Container.style.width = '100%';chart2Container.style.height = '220px'; // 增加高度container.appendChild(chart2Container);const chart2 = new Chart({container: 'container',container: chart2Container,height: 220,autoFit: true, // 自动适应容器大小padding: [50, 100, 70, 100], // 增加内边距,给标签留出更多空间});chart2.options({type: 'point',data,title: {text: 'quantile 比例尺(等频分段)',style: {fontSize: 14,fontWeight: 'bold',},},scale: {color: {type: 'quantile',range: ['#e8f4f8', '#a8d5e5', '#4ba3c3', '#0a6c93'], // 4个颜色分段},value: {nice: true,tickCount: 5, // 减少刻度数量formatter: '.0f', // 使用G2内置的格式化器显示整数},},encode: {x: 'value',y: 'type',color: 'value',shape: 'circle',size: 8,},style: {fillOpacity: 0.8,stroke: '#fff',lineWidth: 1,},legend: {color: {position: 'top',length: 200, // 设置图例长度labelFormatter: '.0f', // 使用G2内置的格式化器显示整数},},axis: {y: false,x: {labelSpacing: 10, // 增加标签间距labelFormatter: '.0f', // 使用G2内置的格式化器显示整数tickCount: 5, // 减少刻度数量},},});chart2.render();return container;
在上面的对比示例中:
下面是一个更复杂的示例,展示如何使用 quantize 比例尺创建多个分段,并自定义数据域:
import { Chart } from '@antv/g2';// 创建一个容器元素const container = document.createElement('div');const chart = new Chart({container: 'container',container,height: 300,});// 生成测试数据const data = Array.from({ length: 100 }, (_, i) => ({value: Math.random() * 100,id: i + 1,}));chart.options({type: 'point',data,scale: {color: {type: 'quantize',domain: [0, 100], // 自定义数据域range: ['#e8f4f8','#d1e6f0','#a8d5e5','#7ec2da','#4ba3c3','#2385ab','#0a6c93',], // 7个颜色对应6个等宽区间},y: {nice: true,},},encode: {x: 'id',y: 'value',color: 'value', // 将值映射到颜色通道shape: 'circle',size: 10,},style: {fillOpacity: 0.8,stroke: '#fff',lineWidth: 1,},legend: {color: {length: 300,labelFormatter: '.0f', // 格式化图例标签为整数},},axis: {y: {title: '数值',},x: {title: 'ID',},},});chart.render();
以下是一个使用 G2 声明式语法(G2Spec)配置 quantize 比例尺的完整示例:
const spec = {type: 'cell',width: 900,height: 300,data: {type: 'fetch',value:'https://gw.alipayobjects.com/os/bmw-prod/89c20fe8-0c6f-46c8-b36b-4cb653dba8ed.json',transform: [{ type: 'map', callback: (d) => ({ salary: d }) }],},scale: {color: {type: 'quantize',range: ['#eeeeee', '#ffc3ce', '#ff0d0d'], // 定义三个颜色区间},},legend: {color: {labelFormatter: '.0s', // 格式化图例标签},},encode: {y: (_, i) => (i % 5) + 1,x: (_, i) => ((i / 5) | 0) + 1,color: 'salary', // 将薪资数据映射到颜色通道},style: {stroke: '#000',inset: 2,},};// 创建一个容器元素const container = document.createElement('div');// 使用 Chart 渲染const chart = new G2.Chart(container);chart.options(spec);chart.render();
这个示例展示了如何使用 G2 声明式语法创建一个使用 quantize 比例尺的热力图,包括以下特性:
使用 quantize 比例尺时需要注意以下几点:
分段边界计算:分段边界由数据域的最小值、最大值和值域数组的长度决定。例如,对于数据域 [0, 100] 和值域长度为 3,边界点为 33.33 和 66.67。
比例尺选择:如果希望按数值范围均匀分段,选择 quantize;如果希望每个分段包含相同数量的数据点,选择 quantile。
数据域设置:可以通过设置 domain
属性来自定义数据域,例如 domain: [0, 100]
。如果不设置,G2 会根据数据自动计算合适的数据域。
数据分布考虑:quantize 比例尺适合处理分布相对均匀的连续数值数据。如果数据分布非常不均匀(如长尾分布),可能更适合使用 quantile 比例尺。
友好刻度:nice
参数设置为 true
时,会扩展数据域的范围,使其边界值更加"友好"(通常是整数或易于理解的数值),这有助于生成更易读的刻度和图例标签。