互联网技术 / 互联网资讯 · 2023年12月14日

pyecharts地图实战解析

在之前关于南丁格尔玫瑰图的讨论中,我们用玫瑰图展示了各国的疫情数据。然而,当涉及的国家数量较多时,玫瑰图并不能有效地传达所有信息。这时,我们自然而然想到了如何在世界地图上展示各国的数据。那么,如何在pyecharts中实现这一点呢?

pyecharts支持多种地图组件,包括Map(地图)、Geo(地理坐标)、Map3D(三维地图)以及BMap(百度地图)。

我们以疫情数据为例,这次使用的是国内各省级行政单位的数据。这是因为在pyecharts的世界地图中,需要使用国家或地区的英文名称来进行匹配,而我们手中的疫情数据则是中文名称,且中国地图使用中文名称匹配各个行政区域。为了避免中文名称转化为英文名称的麻烦,我们这次选择使用国内的数据进行演示。

图样图森破-pyecharts之地图

数据如上所示,接下来我们将逐步进行地图的设置:

from pyecharts import charts, options from pyecharts.commons.utils import JsCode import pandas as pd data = pd.read_excel(‘国内疫情数据.xlsx’) Map1 = charts.Map(init_opts=options.InitOpts(width=’1200px’, height=’800px’))

如往常一样,在初始化配置中,我们设置绘图区域的宽度和高度。接下来进行数据项和地图的配置:

Map1.add(‘累计’, data_pair=[(x[1][‘地区’], x[1][‘累计’]) for x in data.iterrows()], maptype=’china’, is_selected=True, is_roam=True, aspect_scale=0.75, selected_mode=’multiple’, label_opts=options.LabelOpts(is_show=True, formatter=JsCode(‘function(params){ if (params[‘value’]){return params[‘name’] + ”:” + params[‘value’]} else{return ”}}’)), is_map_symbol_show=False)

首先,add方法的第一个参数是数据系列名称。但与一般图表不同的是,Map无法同时显示多个数据系列。如果选中的多个系列在同一区域都有值,则会对其进行求和、平均值、最大值或最小值等展示。

(1) data_pair参数接收的是一个二元数组,第一个元素为区域名称,第二个为区域值。

(2) maptype表示地图类型,世界地图为world,中国地图为china,如果是国内各省级行政单位,则为山东、北京、广东等。

(3) is_selected表示当前数据系列是否默认选中。

(4) is_roam为布尔值,设为True时可以使用鼠标拖拽缩放和移动地图位置。

(5) aspect_scale表示地图的长宽比。

(6) selected_mode表示是否支持选中多个区域,取值可以是布尔型(True、False)和字符串型(single、multiple)。

(7) label_opts是标签项,表示地图上各区域的名称及其数值等说明。我们使用Js传入的formatter参数,使得地图各区域只有在传入了数值且值不为0时才会显示标签。例如,上图中西藏地区为空值,其标签就不再显示。

(8) is_map_symbol_show用来控制地图各区域上是否显示标记,若为True,则会在该区域显示一个小红点,通常位于省会城市的位置。

Map1.set_global_opts(visualmap_opts=options.VisualMapOpts(type_=’color’, is_show=True, pos_bottom=’50%’, pos_left=’0%’, min_=min(data[‘累计’]), max_=max(data[‘累计’]), is_piecewise=True, pieces=[{min: min(data[‘累计’]), max: 200}, {min: 201, max: 300}, {min: 301, max: 400}, {min: 401, max: 500}, {min: 501, max: 600}, {min: 601, max: 700}, {min: 701, max: 800}, {min: 801, max: 900}, {min: 901, max: 1000}, {min: 1000, max: 10000}, {value: 68151, label: ‘湖北’, color: ‘Red’}, {value: 10884, label: ‘香港’, color: ‘Red’}]))

在地图中,通常使用颜色来表示数值大小。Map的全局配置项中包括视觉地图的配置项,指定数值的最小值和最大值(min_和max_),以颜色表示该区间的数值大小。is_piecewise表示是否分段,如果为True,则按照pieces中设置的区间对应颜色分段显示图例,用户可以通过点击图例选中对应颜色的区域并高亮显示:

图样图森破-pyecharts之地图

如果设为False,效果则如下所示:图例为一条连续色卡,用户可以通过鼠标滑动选择对应颜色的区域。但由于无法指定分段区间及颜色,若离差较大,可能会导致颜色单一,无法达到渐变效果。

图样图森破-pyecharts之地图

Map3D可以绘制三维地图,效果如下:

 
图样图森破-pyecharts之地图

通过每个区域上柱子的长短来表示数值大小,直观且立体。以下是代码,参数含义不再赘述:

Map2 = charts.Map3D(init_opts=options.InitOpts(width=’1200px’, height=’800px’)) location = [(‘121.509062’, ‘25.044332’, ‘台湾’), (‘114.502461’, ‘38.045474’, ‘河北’), (‘112.549248’, ‘37.857014’, ‘山西’), (‘111.670801’, ‘40.818311’, ‘内蒙古’), (‘123.429096’, ‘41.796767’, ‘辽宁’), (‘125.3245’, ‘43.886841’, ‘吉林’), (‘126.642464’, ‘45.756967’, ‘黑龙江’), (‘118.767413’, ‘32.041544’, ‘江苏’), (‘120.153576’, ‘30.287459’, ‘浙江’), (‘117.283042’, ‘31.86119’, ‘安徽’), (‘119.306239’, ‘26.075302’, ‘福建’), (‘115.892151’, ‘28.676493’, ‘江西’), (‘117.000923’, ‘36.675807’, ‘山东’), (‘113.665412’, ‘34.757975’, ‘河南’), (‘114.298572’, ‘30.584355’, ‘湖北’), (‘112.982279’, ‘28.19409’, ‘湖南’), (‘113.280637’, ‘23.125178’, ‘广东’), (‘108.320004’, ‘22.82402’, ‘广西’), (‘110.33119’, ‘20.031971’, ‘海南’), (‘104.065735’, ‘30.659462’, ‘四川’), (‘106.713478’, ‘26.578343’, ‘贵州’), (‘102.712251’, ‘25.040609’, ‘云南’), (‘91.132212’, ‘29.660361’, ‘西藏’), (‘108.948024’, ‘34.263161’, ‘陕西’), (‘103.823557’, ‘36.058039’, ‘甘肃’), (‘101.778916’, ‘36.623178’, ‘青海’), (‘106.278179’, ‘38.46637’, ‘宁夏’), (‘87.617733’, ‘43.792818’, ‘新疆’), (‘116.405285’, ‘39.904989’, ‘北京’), (‘117.190182’, ‘39.125596’, ‘天津’), (‘121.472644’, ‘31.231706’, ‘上海’), (‘106.504962’, ‘29.533155’, ‘重庆’), (‘114.173355’, ‘22.320048’, ‘香港’), (‘113.54909’, ‘22.198951’, ‘澳门’)] location_dict = {x[-1]: [x[0], x[1]] for x in location} Map2.add_schema(itemstyle_opts=options.ItemStyleOpts(color=”Rgb(5,101,123)”, opacity=1, border_width=0.8, border_color=”Rgb(62,215,213)”,), map3d_label=options.Map3DLabelOpts(is_show=False, formatter=JsCode(“function(data){return data.name + ” + ” + data.value[2];}”),), emphasis_label_opts=options.LabelOpts(is_show=False, color=”#FFF”, font_size=10, background_color=”Rgba(0,23,11,0)”,), light_opts=options.Map3DLightOpts(main_color=”#FFF”, main_intensity=1.2, main_shadow_quality=”High”, is_main_shadow=False, main_beta=10, ambient_intensity=0.3),).add(series_name=”bar3D”, data_pair=[(x[1][‘地区’], (location_dict[x[1][‘地区’]][0], location_dict[x[1][‘地区’]][1], x[1][‘现有’])) for x in data.iterrows()], type_=ChartType.BAR3D, maptype=’china’, bar_size=1, shading=”lambert”, label_opts=options.LabelOpts(is_show=False, formatter=JsCode(“function(data){return data.name + ” + ” + data.value[2];}”),),).set_global_opts(title_opts=options.TitleOpts(title=”Map3D-Bar3D”)) page = charts.Page() page.add(Map1).add(Map2) page.render(‘Map.html’)