Mapbox GL可视化之热力图

本篇使用Mapbox GL JS实现数据的热力图可视化,以截止到2020-03-01日的新冠疫情作为示例数据。

一 什么是热力图

热力图使用颜色的深浅表示数值的变化,从而表示数据的分布情况,这使得用户可以更容易的理解复杂的数据分布,发现其中的规律。形象地说,热力图展示了数据的“重点”,因此在数据可视化中被广泛应用。

二 初始化地图

1 引入js文件

<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.1/mapbox-gl.css' rel='stylesheet' />
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>

2 构建地图容器

<div id='map'></div>

3 初始化Mapbox GL地图对象

mapboxgl.accessToken = 'your token';
var map = new mapboxgl.Map({
		container: 'map', 
        style: 'mapbox://styles/mapbox/dark-v9', 
        center: [-74.50, 40], 
        zoom: 9
});

4 定义样式

body {
    margin: 0;
    padding: 0;
}

#map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}

5 效果

在这里插入图片描述

三 构建热力图

1 数据示例

{
    "geometry": {
        "coordinates": [
            114.3,
            30.5955
        ],
        "type": "Point"
    },
    "type": "Feature",
    "properties": {
        "new_recovery": 1,
        "new_death": 0,
        "new_diagnosis": 0
    }
}

2 添加数据源

map.addSource('virus-source', {
    "type": "geojson",
    "data": "data.json"
});

3 添加热力图图层

map.addLayer(
    {
        id: "virus-heatmap",
        type: "heatmap",
        source: "virus-source",
        maxzoom: 7,
        layout: {
            visibility: "visible"
        },
        paint: {

        }
    }
);

4 效果

在这里插入图片描述

很明显,这幅图的效果十分不好,首先,其存在着严重的“热力失真”现象,在地图缩放级别很小的情况下,中国的整个东边都好像被感染了,这明显是不符合现实情况的;再者,如果在不同的地图缩放等级下,均采用相同的热力半径,会导致更严重的可视化失衡,因此我们需要进一步改善。

四 Mapbox Expression

在改善之前,有必要介绍Mapbox强大的Expression表达式语言,它被用于定义地图样式内的layout属性、paint属性或filter属性的值,允许使用多个属性对数据进行样式的配置,同时可以应用条件、数学、逻辑和字符串操作符对数据进行操作,十分强大。

1 normal expression

['*', ['pi'], ['^', 3, 2]]:表示3^2 * pi。

2 property expression

['-', 2017, ['number', ['get', 'Constructi'], 2017]]:表示2017 - number of Construction

3 zoom expression

用于使地图的样式随地图的缩放级别而改变,缩放表达式可以用来控制数据密度。

[
    'interpolate', ['linear'], ['zoom'],
    10, ['/', ['-', 2017, ['number', ['get', 'Constructi'], 2017]], 30],
    13, ['/', ['-', 2017, ['number', ['get', 'Constructi'], 2017]], 10],
]

五 改进

Mapbox GL热力图具有三个主要paint样式属性。

1 heatmap-radius

该属性用于设置热力图中每个点的“影响半径”(相当于核密度可视化中的带宽参数),该值越高,外观就会更平滑,详细程度也更低。该属性也可以是一个缩放函数,允许在缩放时调整外观。在实际可视化中,常设置为与缩放级别相关。

2 heatmap-weight

该属性用于定义热力图中某点对热力图贡献的权重,在实际可视化中,常设置为与属性值相关。

3 heatmap-intensity

该属性用于在全局范围内调整热力图外观的强度,值越高,每个点对外观的影响就越大。这种关系是线性的。例如,将heatmap-intensity设置为10.0相当于重复绘制默认值1.0的数据集十次。在实际可视化中,常设置为与缩放级别相关,缩放级别越高,该值应越大,以减少热力失真。

4 heatmap-color

该属性用于定义热力图中最重要的属性-颜色,在实际可视化中,常设置为与热力图密度相关。

5 heatmap-opacity

该属性用于定义热力图的透明度。

6 改进

参考网站https://www.mapbox.cn/coronavirusmap/,修改配色,代码如下。

map.addLayer(
    {
        id: "virus-heatmap",
        type: "heatmap",
        source: "virus-source",
        paint: {
            // 使用new_diagnosis属性
            "heatmap-weight": [
                "interpolate",
                ["linear"],
                ["get", "new_diagnosis"],
                0,
                0,
                1000,
                1
            ],
            "heatmap-intensity": [
                "interpolate",
                ["linear"],
                ["zoom"],
                0,
                3,
                9,
                5
            ],
            // Color ramp for heatmap.  Domain is 0 (low) to 1 (high).
            // Begin color ramp at 0-stop with a 0-transparancy color
            // to create a blur-like effect.
            "heatmap-color": [
                "interpolate",
                ["linear"],
                ["heatmap-density"],
                0,
                "rgba(0, 0, 0, 0)",
                0.1,
                "#927903",
                0.15,
                "#ffd403",
                1,
                "red"
            ],
            // Adjust the heatmap radius by zoom level
            "heatmap-radius": [
                "interpolate",
                ["linear"],
                ["zoom"],
                0,
                2,
                1,
                4,
                2,
                8,
                3,
                16,
                4,
                32,
                5,
                64,
                6,
                128,
                7,
                256,
                8,
                512,
                9,
                1024
            ],
            // Transition from heatmap to circle layer by zoom level
            "heatmap-opacity": [
                "interpolate",
                ["linear"],
                ["zoom"],
                5,
                0.95,
                6,
                0
            ]
        }
    }
);

7 效果
在这里插入图片描述
在这里插入图片描述

八 总结

代码+数据:@GitHub

微信公众号:林木菌

若有任何问题,欢迎留言交流。

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值