Loading...
气泡图是一种多变量图表,是散点图的变体,也可以认为是散点图和百分比区域图的组合。
气泡图最基本的用法是使用三个值来确定每个数据序列,和散点图一样,气泡图将两个维度的数据值分别映射为笛卡尔坐标系上的坐标点,其中 X 和 Y 轴分别代表不同的两个维度的数据,但是不同于散点图的是,气泡图的每个气泡都有分类信息(他们显示在点旁边或者作为图例)。每一个气泡的面积代表第三个数值数据。另外还可以使用不同的颜色来区分分类数据或者其他的数值数据,或者使用亮度或者透明度。表示时间维度的数据时,可以将时间维度作为直角坐标系中的一个维度,或者结合动画来表现数据随着时间的变化情况。
气泡图通常用于比较和展示不同类别圆点(这里我们称为气泡)之间的关系,通过气泡的位置以及面积大小。从整体上看,气泡图可用于分析数据之间的相关性。
需要注意的是,气泡图的数据大小容量有限,气泡太多会使图表难以阅读。但是可以通过增加一些交互行为弥补:隐藏一些信息,当鼠标点击或者悬浮时显示,或者添加一个选项用于重组或者过滤分组类别。
另外,气泡的大小是映射到面积而不是半径或者直径绘制的。因为如果是基于半径或者直径的话,圆的大小不仅会呈指数级变化,而且还会导致视觉误差。
英文名:Bubble Chart
图表类型 | 基础气泡图 |
---|---|
适合的数据 | 多维度数据:至少两个连续型数据字段(X、Y轴)和一个数值型数据字段(气泡大小) |
功能 | 展示多个变量之间的关系,发现数据模式和相关性 |
数据与图形的映射 | 两个连续变量映射到XY坐标 第三个变量映射到气泡的大小 可选的分类型变量映射到气泡的颜色或形状 |
适合的数据条数 | 通常不超过100个数据点,过多会导致图表拥挤 |
视觉设计建议 | 使用半透明气泡避免重叠遮挡 气泡大小范围应适中,避免过大或过小 添加网格线辅助阅读坐标值 |
图表类型 | 对数气泡图 |
---|---|
适合的数据 | 数值范围差异极大的数据集,需要对数变换来展示 |
功能 | 处理数据跨度很大的情况,如人口数据、GDP数据等 |
数据与图形的映射 | 与基础气泡图相同,但采用对数比例尺 两个连续变量映射到XY坐标 第三个变量通过对数映射到气泡的大小 |
使用场景 | 当数据出现指数增长或数值范围跨越多个数量级时 |
实现方法 | 使用scale: { size: { type: 'log', range: [4, 20] } } 配置对数比例尺 |
注意事项 | 应在图例或标签中明确指出使用了对数变换,避免误导读者 |
气泡图最适合用于以下几类场景:
下图展示了不同国家人均GDP、预期寿命与人口数量的关系,同时用颜色区分了不同大洲,有效地在一个图表中展现了四个维度的数据。
country(国家) | GDP(人均GDP) | lifeExpectancy(预期寿命) | population(人口) | continent(大洲) |
---|---|---|---|---|
China | 12547 | 76.9 | 1403500365 | Asia |
United States | 59532 | 78.5 | 321773631 | Americas |
India | 6427 | 68.3 | 1324517249 | Asia |
Japan | 38428 | 83.9 | 127141000 | Asia |
Germany | 46136 | 81.0 | 82695000 | Europe |
... | ... | ... | ... | ... |
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});chart.options({type: 'point',autoFit: true,data: {type: 'fetch',value: 'https://gw.alipayobjects.com/os/antvdemo/assets/data/bubble.json',},encode: {x: 'GDP',y: 'LifeExpectancy',size: 'Population',color: 'continent',shape: 'point'},scale: {size: { type: 'log', range: [4, 20] }},style: {fillOpacity: 0.3,lineWidth: 1},legend: {size: false}});chart.render();
分析 :
GDP
字段映射到 X 轴,表示国家人均GDP,可以看出发达国家集中在右侧LifeExpectancy
字段映射到 Y 轴,表示国民预期寿命,能够观察到人均GDP与预期寿命有正相关性Population
字段映射到气泡大小,通过对数比例尺处理,使得中国、印度等人口大国清晰可见continent
字段映射到颜色,可以看出不同大洲国家的聚类分布洞察:通过此图,我们可以直观地观察到:
例子 1: 数据点过多或气泡重叠过度
当数据点超过100个或气泡严重重叠时,气泡图可能变得混乱难以阅读。在这种情况下,可以考虑使用热力图或分面图表。
以下是一个包含大量数据点的气泡图示例,可以看到随着数据点的增加,气泡之间的重叠让图表变得难以解读:
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});// 生成200个随机数据点const data = Array.from({ length: 200 }, () => ({x: Math.random() * 100,y: Math.random() * 100,size: Math.random() * 20 + 5,category: ['A', 'B', 'C', 'D'][Math.floor(Math.random() * 4)]}));chart.options({type: 'point',autoFit: true,data,encode: {x: 'x',y: 'y',size: 'size',color: 'category'},style: {fillOpacity: 0.3,lineWidth: 1},});chart.render();
例子 2: 只有两个变量需要比较
当只需比较两个变量之间的关系时,散点图比气泡图更简洁有效。气泡图的第三个变量(气泡大小)如果没有必要,反而会增加认知负担。
例子 3: 展示趋势变化的时序数据
气泡图不适合展示时序趋势数据。对于需要展示随时间变化趋势的数据,折线图或面积图是更好的选择。
下面是一个不使用气泡图而使用折线图展示时序数据的例子:
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});chart.options({type: 'view',autoFit: true,data: [{ day: '2015/9/1', share: 10, volume: 1200 },{ day: '2015/9/5', share: 20, volume: 2100 },{ day: '2015/9/10', share: 32, volume: 3400 },{ day: '2015/9/15', share: 45, volume: 2900 },{ day: '2015/9/20', share: 51, volume: 4100 },{ day: '2015/9/25', share: 45, volume: 3800 },{ day: '2015/9/30', share: 40, volume: 2700 },],encode: { x: 'day', y: 'share' },axis: {y: {title: '股价',},x: {title: '日期',},},children: [{type: 'line',style: {lineWidth: 3,},},],});chart.render();
如果确实需要在时序数据中加入第三个维度的信息,可以使用带有大小编码的时间序列气泡图:
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});chart.options({type: 'point',autoFit: true,data: [{ day: '2015/9/1', share: 10, volume: 1200 },{ day: '2015/9/5', share: 20, volume: 2100 },{ day: '2015/9/10', share: 32, volume: 3400 },{ day: '2015/9/15', share: 45, volume: 2900 },{ day: '2015/9/20', share: 51, volume: 4100 },{ day: '2015/9/25', share: 45, volume: 3800 },{ day: '2015/9/30', share: 40, volume: 2700 },],encode: {x: 'day',y: 'share',size: 'volume'},scale: {size: { range: [10, 40] }},style: {fillOpacity: 0.6,stroke: '#1890ff',fill: '#1890ff'},axis: {y: { title: '股价' },x: { title: '日期' }},annotations: [{type: 'line',data: [{ day: '2015/9/1', share: 10 },{ day: '2015/9/5', share: 20 },{ day: '2015/9/10', share: 32 },{ day: '2015/9/15', share: 45 },{ day: '2015/9/20', share: 51 },{ day: '2015/9/25', share: 45 },{ day: '2015/9/30', share: 40 },],encode: { x: 'day', y: 'share' },style: { stroke: '#1890ff', lineWidth: 2 }}]});chart.render();
图表类型 | 主要特点 | 适用场景 | 数据维度 |
---|---|---|---|
气泡图 | 通过点的大小编码额外维度 | 多变量关系分析 | 3-4个变量(X、Y、大小、颜色) |
散点图 | 仅展示点的位置 | 二维相关性分析 | 2-3个变量(X、Y、颜色) |
热力图 | 通过颜色深浅展示密度或量值 | 展示分布密度 | 3个变量(X、Y、颜色强度) |
图表类型 | 坐标系统 | 数据约束 | 应用场景 |
---|---|---|---|
气泡图 | 抽象坐标系 | 可使用任意数值作为XY坐标 | 多维数据关系可视化 |
气泡地图 | 地理坐标系 | 点位置受地理坐标约束 | 地理数据中多变量分析 |
散点地图 | 地理坐标系 | 点位置受地理坐标约束 | 地理位置的简单分布 |
气泡大小选择
数据处理
标签和交互
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});chart.options({type: 'point',autoFit: true,data: [{ x: 10, y: 20, size: 20, category: 'A', name: '项目1' },{ x: 20, y: 40, size: 35, category: 'A', name: '项目2' },{ x: 30, y: 30, size: 15, category: 'B', name: '项目3' },{ x: 40, y: 60, size: 40, category: 'B', name: '项目4' },{ x: 50, y: 50, size: 25, category: 'C', name: '项目5' },],encode: {x: 'x',y: 'y',size: 'size',color: 'category',shape: 'point'},style: {fillOpacity: 0.6,lineWidth: 1},tooltip: {items: [{ field: 'name', name: '项目名称' },{ field: 'x', name: 'X值' },{ field: 'y', name: 'Y值' },{ field: 'size', name: '大小' },]},interaction: [{ type: 'tooltip' },{ type: 'elementHighlight' }]});chart.render();