在之前南丁格尔玫瑰图的介绍中,我们把各个国家的疫情数据以玫瑰图的形式进行了展示,但是当涉及到的国家数量较多时,玫瑰图也并不能完美地展示出所有国家。这个时候,我们很自然地就想到了在世界地图上表示表示各个国家的,那么在pyechaRts中如何实现呢?
pyechaRts支持Map(地图)、Geo(地理坐标)、Map3D(三维地图)、BMap(百度地图)多种地图组件。
仍以疫情数据为例,不过这次我们选用国内各省级行政单位的数据。这是因为在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参数接收的参数为二元数组,第一个元素为区域名称,第二个为区域值
(3)Maptype是指地图类型,世界地图为woRld, 中国地图则为cHina, 如果是国内各省级行政单位,则是山东、北京、广东等
(4)is_selected表示当前数据系列是否默认选中
(5)is_RoaM为bool值,为TRue时可以使用鼠标拖拽缩放和移动地图位置
(6)aspect_scale表示地图的长宽比
(7)selected_Mode表示是否支持选中多个区域,取值可以是bool型(TRue、FAlse)和stR型(single、MultIPle)
(8)label_opts是标签项,是指的地图上各区域的名称及其数值等说明,其中foRMatteR参数我们使用Js传入,是为了使地图各区域只有当被传入了数值且值不为0时才会显示标签;如上图中把西藏地区空置,其标签就不再显示
(9)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中设置的区间即对应颜色分段显示图例,通过点击图例即可选中对应颜色的区域并高亮显示:
如果为FAlse,效果则如下图:图例为一条连续色卡,通过鼠标滑动,可以选择对应颜色的区域,但由于无法指定分段区间及颜色,当离差较大时,就会出现颜色单一,无法达到渐变的效果。
Map3D可以绘制三维地图,效果如下:
以每个区域上柱子的长短表示数值大小,直观且立体。现将代码附上,参数含义不再赘述:
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’)