热力图完全指南 - heatmap
📋 概述
热力图(Heatmap) 通过颜色深浅展示数据矩阵中各位置的数值大小,适用于展示相关性矩阵、时间分布、密度图等场景。它是发现数据模式和异常点的利器。
核心价值
- 相关性分析:展示变量间的相关系数
- 时间分布:一周24小时的活动密度
- 空间密度:地理区域的热度分布
- 模式识别:快速发现数据的聚集和异常
🎯 核心概念
1. 基础热力图
javascript
// 数据结构:[x, y, value]
option = {
series: [{
type: 'heatmap',
data: [
[0, 0, 10], [0, 1, 20], [0, 2, 30],
[1, 0, 40], [1, 1, 50], [1, 2, 60],
[2, 0, 70], [2, 1, 80], [2, 2, 90]
]
}]
};1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
2. 视觉映射
javascript
option = {
visualMap: {
min: 0,
max: 100,
calculable: true,
inRange: {
color: ['#313695', '#4575b4', '#74add1', '#fee090', '#d73027']
}
},
series: [{
type: 'heatmap',
data: heatmapData
}]
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
🔧 详细配置项
完整热力图配置
javascript
const hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a',
'7a', '8a', '9a', '10a', '11a',
'12p', '1p', '2p', '3p', '4p', '5p',
'6p', '7p', '8p', '9p', '10p', '11p'];
const days = ['Saturday', 'Friday', 'Thursday',
'Wednesday', 'Tuesday', 'Monday', 'Sunday'];
// 生成模拟数据
const data = [];
for (let i = 0; i < 7; i++) {
for (let j = 0; j < 24; j++) {
const value = Math.floor(Math.random() * 100);
data.push([j, i, value]);
}
}
option = {
title: {
text: '用户活跃度热力图',
subtext: '一周24小时分布',
left: 'center'
},
tooltip: {
position: 'top',
formatter: function(params) {
return `${days[params.data[1]]} ${hours[params.data[0]]}<br/>
活跃度: ${params.data[2]}`;
}
},
grid: {
height: '60%',
top: '15%'
},
xAxis: {
type: 'category',
data: hours,
splitArea: {
show: true
}
},
yAxis: {
type: 'category',
data: days,
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: 100,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '5%',
inRange: {
color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8',
'#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
}
},
series: [{
name: '活跃度',
type: 'heatmap',
data: data,
label: {
show: false // 数据量大时关闭标签
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};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
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
💡 实战案例
案例1:相关性矩阵
javascript
const variables = ['年龄', '收入', '教育', '消费', '储蓄', '投资'];
const correlationMatrix = [
[1.00, 0.65, 0.45, 0.30, -0.20, 0.50],
[0.65, 1.00, 0.70, 0.55, -0.10, 0.60],
[0.45, 0.70, 1.00, 0.40, -0.05, 0.55],
[0.30, 0.55, 0.40, 1.00, -0.45, 0.35],
[-0.20, -0.10, -0.05, -0.45, 1.00, 0.25],
[0.50, 0.60, 0.55, 0.35, 0.25, 1.00]
];
const data = [];
for (let i = 0; i < variables.length; i++) {
for (let j = 0; j < variables.length; j++) {
data.push([j, i, correlationMatrix[i][j]]);
}
}
option = {
title: {
text: '变量相关性矩阵',
left: 'center'
},
tooltip: {
formatter: function(params) {
return `${variables[params.data[1]]} vs ${variables[params.data[0]]}<br/>
相关系数: ${params.data[2].toFixed(2)}`;
}
},
grid: {
height: '70%',
top: '10%'
},
xAxis: {
type: 'category',
data: variables,
splitArea: { show: true }
},
yAxis: {
type: 'category',
data: variables,
splitArea: { show: true }
},
visualMap: {
min: -1,
max: 1,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '5%',
inRange: {
color: ['#d73027', '#f46d43', '#fee090', '#e0f3f8', '#4575b4', '#313695']
},
formatter: function(value) {
return value.toFixed(1);
}
},
series: [{
type: 'heatmap',
data: data,
label: {
show: true,
formatter: function(params) {
return params.data[2].toFixed(2);
}
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};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
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
案例2:日历热力图
javascript
// GitHub风格的提交记录热力图
const startDate = new Date('2023-01-01');
const endDate = new Date('2023-12-31');
const calendarData = [];
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
const dateStr = d.toISOString().split('T')[0];
const commits = Math.floor(Math.random() * 10);
calendarData.push([dateStr, commits]);
}
option = {
title: {
text: '代码提交热力图',
left: 'center'
},
tooltip: {
formatter: function(params) {
return `${params.data[0]}<br/>提交次数: ${params.data[1]}`;
}
},
visualMap: {
min: 0,
max: 10,
calculable: true,
orient: 'horizontal',
left: 'center',
top: 'top',
inRange: {
color: ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']
}
},
calendar: {
top: 80,
left: 30,
right: 30,
cellSize: ['auto', 13],
range: '2023',
itemStyle: {
borderWidth: 0.5
},
yearLabel: { show: false }
},
series: [{
type: 'heatmap',
coordinateSystem: 'calendar',
data: calendarData
}]
};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
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
⚠️ 常见问题
问题1:颜色映射不准确
解决:
javascript
visualMap: {
min: actualMin, // 使用实际最小值
max: actualMax, // 使用实际最大值
inRange: {
color: [...] // 确保颜色数组足够长
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
问题2:标签重叠
解决:
javascript
series: [{
type: 'heatmap',
label: {
show: true,
fontSize: 8, // 缩小字体
formatter: function(params) {
return params.data[2] > 50 ? params.data[2] : ''; // 只显示重要值
}
}
}]1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
🎯 最佳实践
1. 选择合适的配色
javascript
// diverging(发散型):有正负值
color: ['#d73027', '#fee090', '#1a9850']
// sequential(顺序型):从低到高
color: ['#ffffcc', '#a1dab4', '#41b6c4', '#225ea8']
// categorical(分类型):离散类别
color: ['#5470c6', '#91cc75', '#fac858']1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
2. 性能优化
javascript
series: [{
type: 'heatmap',
data: hugeData,
progressive: 5000,
progressiveThreshold: 10000
}]1
2
3
4
5
6
2
3
4
5
6
📊 性能指标
| 数据量 | 渲染时间 | 建议 |
|---|---|---|
| <1000格 | 15ms | 无限制 |
| 1000-5000格 | 40ms | 正常 |
| >5000格 | 100ms | 启用progressive |
🔗 相关链接
- visualMap视觉映射
- 日历坐标系
💎 总结
热力图核心价值:
- ✅ 颜色直观展示数值
- ✅ 发现数据模式
- ✅ 相关性分析利器
- ✅ 时间密度可视化
掌握热力图,让数据关系一目了然!🌡️
热力图数据分布
{
"title": {
"text": "每周活动热力图",
"left": "center"
},
"tooltip": {
"position": "top"
},
"grid": {
"height": "60%",
"top": "15%"
},
"xAxis": {
"type": "category",
"data": [
"周一",
"周二",
"周三",
"周四",
"周五",
"周六",
"周日"
],
"splitArea": {
"show": true
}
},
"yAxis": {
"type": "category",
"data": [
"0:00",
"2:00",
"4:00",
"6:00",
"8:00",
"10:00",
"12:00",
"14:00",
"16:00",
"18:00",
"20:00",
"22:00"
],
"splitArea": {
"show": true
}
},
"visualMap": {
"min": 0,
"max": 100,
"calculable": true,
"orient": "horizontal",
"left": "center",
"bottom": "5%"
},
"series": [
{
"type": "heatmap",
"data": [
[
0,
0,
87
],
[
0,
1,
6
],
[
0,
2,
60
],
[
0,
3,
64
],
[
0,
4,
97
],
[
0,
5,
62
],
[
0,
6,
42
],
[
0,
7,
92
],
[
0,
8,
80
],
[
0,
9,
23
],
[
0,
10,
68
],
[
0,
11,
24
],
[
1,
0,
59
],
[
1,
1,
6
],
[
1,
2,
98
],
[
1,
3,
37
],
[
1,
4,
19
],
[
1,
5,
46
],
[
1,
6,
67
],
[
1,
7,
23
],
[
1,
8,
39
],
[
1,
9,
11
],
[
1,
10,
88
],
[
1,
11,
60
],
[
2,
0,
37
],
[
2,
1,
81
],
[
2,
2,
24
],
[
2,
3,
61
],
[
2,
4,
13
],
[
2,
5,
57
],
[
2,
6,
86
],
[
2,
7,
31
],
[
2,
8,
55
],
[
2,
9,
37
],
[
2,
10,
55
],
[
2,
11,
67
],
[
3,
0,
9
],
[
3,
1,
63
],
[
3,
2,
50
],
[
3,
3,
60
],
[
3,
4,
44
],
[
3,
5,
55
],
[
3,
6,
70
],
[
3,
7,
43
],
[
3,
8,
40
],
[
3,
9,
73
],
[
3,
10,
94
],
[
3,
11,
7
],
[
4,
0,
59
],
[
4,
1,
26
],
[
4,
2,
47
],
[
4,
3,
53
],
[
4,
4,
2
],
[
4,
5,
76
],
[
4,
6,
52
],
[
4,
7,
10
],
[
4,
8,
22
],
[
4,
9,
49
],
[
4,
10,
0
],
[
4,
11,
83
],
[
5,
0,
51
],
[
5,
1,
44
],
[
5,
2,
33
],
[
5,
3,
92
],
[
5,
4,
42
],
[
5,
5,
62
],
[
5,
6,
62
],
[
5,
7,
51
],
[
5,
8,
5
],
[
5,
9,
78
],
[
5,
10,
47
],
[
5,
11,
74
],
[
6,
0,
18
],
[
6,
1,
54
],
[
6,
2,
72
],
[
6,
3,
71
],
[
6,
4,
68
],
[
6,
5,
54
],
[
6,
6,
52
],
[
6,
7,
25
],
[
6,
8,
84
],
[
6,
9,
60
],
[
6,
10,
47
],
[
6,
11,
99
]
],
"label": {
"show": false
}
}
]
}