平行坐标系完全指南 - parallel
📋 概述
平行坐标系(Parallel Coordinates) 是一种用于展示高维数据的多变量分析图表。它通过多条平行的轴线和连接线,直观展示每个数据点在各个维度上的取值,是多维数据探索的利器。
核心价值
- 多维展示:在二维平面展示4+维度数据
- 模式识别:发现数据聚类和异常值
- 相关性分析:观察维度间的关系
- 数据筛选:交互式过滤和刷选
🎯 核心概念
1. 基础平行坐标图
javascript
option = {
parallel: {
left: '5%',
right: '13%',
bottom: '10%',
top: '15%',
parallelAxisDefault: {
type: 'value',
name: ''
}
},
parallelAxis: [
{ dim: 0, name: '维度1' },
{ dim: 1, name: '维度2' },
{ dim: 2, name: '维度3' },
{ dim: 3, name: '维度4' }
],
series: [{
type: 'parallel',
data: [
[10, 20, 30, 40],
[15, 25, 35, 45],
[20, 30, 40, 50]
]
}]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2. 数据结构
javascript
// 每条数据线是一个数组,对应各个维度的值
const multiDimData = [
[85, 90, 78, 92, 88], // 学生A: [语文, 数学, 英语, 物理, 化学]
[92, 88, 95, 85, 90], // 学生B
[78, 95, 85, 92, 80] // 学生C
];1
2
3
4
5
6
2
3
4
5
6
🔧 详细配置项
完整平行坐标图配置
javascript
option = {
title: {
text: '学生成绩多维分析',
subtext: '平行坐标系展示五科成绩',
left: 'center'
},
tooltip: {
padding: 10,
backgroundColor: '#222',
borderColor: '#777',
borderWidth: 1,
formatter: function(obj) {
const value = obj.value;
return `<strong>${obj.name}</strong><br/>
语文: ${value[0]}<br/>
数学: ${value[1]}<br/>
英语: ${value[2]}<br/>
物理: ${value[3]}<br/>
化学: ${value[4]}`;
}
},
parallel: {
left: '5%',
right: '13%',
bottom: '10%',
top: '15%',
// === 平行轴默认配置 ===
parallelAxisDefault: {
type: 'value',
name: '',
nameLocation: 'end',
nameGap: 20,
// 轴线样式
axisLine: {
lineStyle: {
color: '#888',
width: 2
}
},
// 刻度标签
axisLabel: {
fontSize: 11,
color: '#333'
},
// 分割线
splitLine: {
show: true,
lineStyle: {
color: '#eee',
width: 1
}
}
}
},
parallelAxis: [
{
dim: 0,
name: '语文',
max: 100,
min: 0
},
{
dim: 1,
name: '数学',
max: 100,
min: 0
},
{
dim: 2,
name: '英语',
max: 100,
min: 0
},
{
dim: 3,
name: '物理',
max: 100,
min: 0
},
{
dim: 4,
name: '化学',
max: 100,
min: 0
}
],
series: [{
name: '学生成绩',
type: 'parallel',
lineStyle: {
width: 2,
opacity: 0.5
},
emphasis: {
lineStyle: {
width: 4,
opacity: 1
}
},
data: [
{ value: [85, 90, 78, 92, 88], name: '张三' },
{ value: [92, 88, 95, 85, 90], name: '李四' },
{ value: [78, 95, 85, 92, 80], name: '王五' },
{ value: [90, 82, 88, 78, 95], name: '赵六' },
{ value: [88, 92, 90, 85, 82], name: '钱七' }
]
}]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
💡 实战案例
案例1:汽车性能多维对比
javascript
const cars = [
{ name: 'Tesla Model 3', dims: [90, 85, 95, 80, 88, 92] },
{ name: 'BMW i4', dims: [85, 90, 88, 92, 85, 88] },
{ name: 'Audi e-tron GT', dims: [88, 88, 90, 90, 87, 90] },
{ name: 'Porsche Taycan', dims: [82, 95, 85, 95, 90, 85] },
{ name: 'Mercedes EQE', dims: [87, 82, 88, 85, 92, 87] },
{ name: 'Lucid Air', dims: [92, 80, 92, 78, 85, 90] }
];
const dimensions = ['续航', '加速', '操控', '舒适', '安全', '科技'];
const parallelData = cars.map(car => ({
name: car.name,
value: car.dims
}));
option = {
title: {
text: '电动汽车性能对比',
left: 'center'
},
tooltip: {
formatter: function(obj) {
let html = `<strong>${obj.name}</strong><br/>`;
dimensions.forEach((dim, i) => {
html += `${dim}: ${obj.value[i]}/100<br/>`;
});
return html;
}
},
parallel: {
left: '5%',
right: '10%',
bottom: '10%',
top: '15%'
},
parallelAxis: dimensions.map((dim, index) => ({
dim: index,
name: dim,
max: 100,
min: 0,
nameTextStyle: {
fontSize: 12,
fontWeight: 'bold'
}
})),
series: [{
type: 'parallel',
data: parallelData,
lineStyle: {
width: 3,
opacity: 0.6
},
emphasis: {
lineStyle: {
width: 5,
opacity: 1,
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.3)'
}
},
itemStyle: {
color: '#5470c6'
}
}]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
案例2:带视觉映射的平行坐标
javascript
option = {
title: {
text: '鸢尾花数据集可视化',
left: 'center'
},
tooltip: {
formatter: function(obj) {
return `${obj.name}<br/>
花萼长度: ${obj.value[0]}cm<br/>
花萼宽度: ${obj.value[1]}cm<br/>
花瓣长度: ${obj.value[2]}cm<br/>
花瓣宽度: ${obj.value[3]}cm`;
}
},
visualMap: {
type: 'piecewise',
categories: ['Setosa', 'Versicolor', 'Virginica'],
dimension: 4, // 使用第5维(类别)进行颜色映射
inRange: {
color: ['#5470c6', '#91cc75', '#fac858']
},
orient: 'vertical',
right: 10,
top: 'center'
},
parallel: {
left: '5%',
right: '15%',
bottom: '10%',
top: '15%'
},
parallelAxis: [
{ dim: 0, name: '花萼长度' },
{ dim: 1, name: '花萼宽度' },
{ dim: 2, name: '花瓣长度' },
{ dim: 3, name: '花瓣宽度' },
{ dim: 4, name: '品种', type: 'category' }
],
series: [{
type: 'parallel',
data: irisData, // 150个样本
lineStyle: {
width: 2,
opacity: 0.3
}
}]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
⚠️ 常见问题
问题1:线条过于混乱
解决:
javascript
series: [{
type: 'parallel',
lineStyle: {
opacity: 0.2 // 降低透明度
},
emphasis: {
lineStyle: {
opacity: 1 // 悬停时高亮
}
}
}]1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
问题2:维度太多拥挤
解决:
javascript
// 限制显示的维度数量
parallelAxis: [
{ dim: 0, name: '重要维度1' },
{ dim: 1, name: '重要维度2' },
{ dim: 2, name: '重要维度3' },
// 最多6-8个维度
]1
2
3
4
5
6
7
2
3
4
5
6
7
🎯 最佳实践
1. 维度排序
javascript
// 将相关性强的维度放在一起
// 或者按业务逻辑排序
parallelAxis: [
{ dim: 0, name: '输入1' },
{ dim: 1, name: '输入2' },
{ dim: 2, name: '输出1' },
{ dim: 3, name: '输出2' }
]1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
2. 交互增强
javascript
// 启用刷选
parallel: {
parallelAxisDefault: {
areaSelectStyle: {
width: 20,
borderWidth: 1,
borderColor: '#5470c6',
color: '#5470c6',
opacity: 0.3
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
3. 颜色编码
javascript
// 根据类别或数值范围着色
visualMap: {
dimension: 0,
min: 0,
max: 100,
inRange: {
color: ['#313695', '#4575b4', '#fee090', '#d73027']
}
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
📊 性能指标
| 数据量 | 渲染时间 | 建议 |
|---|---|---|
| <100条 | 15ms | 无限制 |
| 100-500条 | 40ms | 正常 |
| >500条 | 100ms | 降低opacity |
🔗 相关链接
- 散点图高级.md)
- visualMap视觉映射
💎 总结
平行坐标系核心价值:
- ✅ 高维数据二维展示
- ✅ 发现数据聚类模式
- ✅ 识别异常值和离群点
- ✅ 多维度对比分析
适用场景:
- 多指标性能评估
- 科学实验数据分析
- 金融风险评估
- 生物信息学研究
掌握平行坐标系,让多维数据分析更清晰!📐
平行坐标系数据对比
{
"title": {
"text": "汽车性能对比",
"left": "center"
},
"tooltip": {
"trigger": "item"
},
"parallelAxis": [
{
"dim": 0,
"name": "价格(万)",
"min": 10,
"max": 50
},
{
"dim": 1,
"name": "油耗(L)",
"min": 5,
"max": 15
},
{
"dim": 2,
"name": "功率(kW)",
"min": 80,
"max": 200
},
{
"dim": 3,
"name": "扭矩(N·m)",
"min": 150,
"max": 400
}
],
"parallel": {
"left": "5%",
"right": "5%",
"bottom": "10%",
"top": "15%"
},
"series": [
{
"type": "parallel",
"lineStyle": {
"width": 2
},
"data": [
[
15,
6.5,
110,
200
],
[
25,
8,
150,
300
],
[
35,
10.5,
180,
350
],
[
20,
7.5,
130,
250
]
]
}
]
}