圖樣圖森破-pyecharts之地圖
在之前南丁格爾玫瑰圖的介紹中,我們把各個國家的疫情數據以玫瑰圖的形式進行了展示,但是當涉及到的國家數量較多時,玫瑰圖也并不能完美地展示出所有國家。這個時候,我們很自然地就想到了在世界地圖上表示表示各個國家的,那么在pyecharts中如何實現呢?
pyecharts支持Map(地圖)、Geo(地理坐標)、Map3D(三維地圖)、BMap(百度地圖)多種地圖組件。
仍以疫情數據為例,不過這次我們選用國內各省級行政單位的數據。這是因為在pyecharts的世界地圖中,是使用國家或地區(qū)的英文名稱來匹配的,而我們獲取到的疫情數據則都是中文名稱,而中國地圖上是使用中文名稱來匹配各行政區(qū)域的。為免中文名稱轉換英文名稱的麻煩,因此我們本次使用國內的數據來做示范。
數據如上所示,下面我們按部就班地開始地圖的各項設置:
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'))
與往常一樣,在初始化配置中我們設置繪圖區(qū)域的寬和高。接下來是數據項和地圖的配置:
map1.add('累計', data_pair=[(x[1]['地區(qū)'], 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中對多個數據系列不能同時顯示,當你選中的多個系列在同一區(qū)域都有值的話,那么就會對其進行求和或平均值、最大值、最小值之一來進行圖表展示。
(1) data_pair參數接收的參數為二元數組,第一個元素為區(qū)域名稱,第二個為區(qū)域值
(3)maptype是指地圖類型,世界地圖為“world”,中國地圖則為“china”,如果是國內各省級行政單位,則是“山東”、“北京”、“廣東”等
(4)is_selected表示當前數據系列是否默認選中
(5)is_roam為bool值,為True時可以使用鼠標拖拽縮放和移動地圖位置
(6)aspect_scale表示地圖的長寬比
(7)selected_mode表示是否支持選中多個區(qū)域,取值可以是bool型(True、False)和str型(single、multiple)
(8)label_opts是標簽項,是指的地圖上各區(qū)域的名稱及其數值等說明,其中formatter參數我們使用Js傳入,是為了使地圖各區(qū)域只有當被傳入了數值且值不為0時才會顯示標簽;如上圖中把西藏地區(qū)空置,其標簽就不再顯示
(9)is_map_symbol_show用來控制地圖各區(qū)域上是否顯示標記,如果為True則會在該區(qū)域有一個小紅點,一般是在其省會城市的位置
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_),即可以顏色表示此區(qū)間數值大小。其中is_piecewise表示是否分段,如果為True則像下圖一樣,按照pieces中設置的區(qū)間即對應顏色分段顯示圖例,通過點擊圖例即可選中對應顏色的區(qū)域并高亮顯示:
如果為False,效果則如下圖:圖例為一條連續(xù)色卡,通過鼠標滑動,可以選擇對應顏色的區(qū)域,但由于無法指定分段區(qū)間及顏色,當離差較大時,就會出現顏色單一,無法達到漸變的效果。
Map3D可以繪制三維地圖,效果如下:
??
以每個區(qū)域上柱子的長短表示數值大小,直觀且立體。現將代碼附上,參數含義不再贅述:
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]['地區(qū)'], (location_dict[x[1]['地區(qū)']][0], location_dict[x[1]['地區(qū)']][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')