如何用位置数据做热力图(并且不误导任何人)
带宽、归一化、配色分级,每一项都会改变结论。这三件事没交代清楚的热力图,只是装饰。
- 作者
- HuiTu Technology
- 发布时间
热力图看上去很客观。它画的是数据在哪里密集,而图像总让人觉得那就是事实。实际上,同一批点,取决于分析者做了哪些选择,可以画出一个大范围热点,也可以画出五个彼此分开的热点,而两张图看起来一样权威。
本文讲的是决定一张热力图究竟在说什么的五个选择,以及每个选择要怎么做才站得住脚。
1. 先把点数据清洗干净
密度图会放大数据错误,而不是掩盖它们。最能毁掉一张热力图的错误是中心点回退:地理编码找不到具体地址时,很多服务会直接返回邮编区或城市的中心点。这些记录堆在同一个坐标上,会造出一个纯属人为的热点。
-- Coordinates shared by many records are almost always centroid fallbacks
SELECT ROUND(lat::numeric, 5) AS lat,
ROUND(lon::numeric, 5) AS lon,
COUNT(*) AS records
FROM points
GROUP BY 1, 2
HAVING COUNT(*) > 5
ORDER BY records DESC;2. 投影到等面积坐标系
绝不要以度为单位计算密度。经度一度对应的实际距离会随着远离赤道而缩短,所以以度为半径的核函数,在研究区域北部覆盖的实际面积小于南部。做任何距离计算之前,先重投影到某个 UTM 分带、国家坐标网或等面积投影。
3. 选定空间聚合方法
| 方法 | 输出 | 适用情形 |
|---|---|---|
| 核密度估计 | 平滑连续的栅格面 | 想看清一个现象的整体形态 |
| 六边形分箱 | 等面积多边形,带计数值 | 需要按单元做关联、对比或汇报 |
| 方形格网 | 格网单元,带计数值 | 结果必须与既有栅格或统计格网对齐 |
分箱时六边形优于方形,因为六边形的每个相邻单元距离相同,不会像方形格网那样沿着行列轴向产生方向性的人为纹理。
4. 选定带宽,并逐个验证
带宽是每个点的影响半径,也是整张图里影响最大的一个参数。设得太小,看到的只是一个个孤立的点;设得太大,所有东西糊成一团,中心落在最热闹的那片区域。
- 从决策本身的尺度出发。步行可达的零售问题大致对应 200 到 400 米,区域级的服务覆盖问题大致对应 2 到 5 公里。
- 用三到四个带宽各做一版密度面,而不是只做一版。
- 看哪些热点在所有版本里都稳定存在。那些才是真实的结构;只在某一个带宽下出现的,是这个参数选择带来的假象。
- 把带宽标在图上。一个既没有单位也没有半径说明的密度图例,是没法解读的。
5. 用正确的分母做归一化
这一步最常被跳过,而它往往正是改变结论的那一步。几乎任何人类活动的原始计数,画出来都会在市中心形成热点,因为人本来就在那里。这样的地图只是把人口密度重新发现了一遍,代价还不小。
| 要回答的问题 | 归一化分母 |
|---|---|
| 居民在哪里产生的活动最多? | 常住人口 |
| 白天的活动集中在哪里? | 就业人口 |
| 哪个品类在哪里供给过剩? | 竞争门店数或营业面积 |
| 单位暴露量下风险最高的地方在哪里? | 出行次数、到访次数或暴露时长 |
| 绝对量最大的地方在哪里? | 不需要分母,此时原始计数就是对的 |
通常的做法是原始密度面和归一化密度面各做一版。两者之间的差异,往往才是整个分析里信息量最大的产出。
然后检验这些热点是不是真的
热力图只告诉你哪里数值高,不会告诉你这种集聚是否超出了随机分布本来就会产生的程度。Getis-Ord Gi* 能回答这个问题:它为每个单元给出 z 值和置信水平,于是热点从「你选的一种颜色」变成一个可以拿去辩护的结论。
import geopandas as gpd
from libpysal.weights import Queen
from esda.getisord import G_Local
hexes = gpd.read_file("hexbins.gpkg")
weights = Queen.from_dataframe(hexes)
weights.transform = "r"
gi = G_Local(hexes["count_per_1k"], weights, permutations=999)
hexes["z"] = gi.Zs
hexes["p"] = gi.p_sim
hexes["hotspot"] = (hexes.z > 1.96) & (hexes.p < 0.05)最后,诚实地选配色
- 用感知均匀的色带,比如 viridis 或 magma。彩虹色带会凭空造出数据里并不存在的分界。
- 写明分级方法。同一批数据,用分位数、等间距和自然断点分级,画出来的图差别极大。
- 图例要标真实单位,而不是从「低」到「高」。
- 发布之前,检查色带在色觉障碍下是否仍然可读。