
各國人口數(shù)據(jù)(2020)
利用Pyecharts繪制地圖時,用worldometers的population數(shù)據(jù)繪制了世界各國人口數(shù)據(jù)地圖,如上圖。
看到worldometers中的數(shù)據(jù)還包括了國土面積、增長率等其它數(shù)據(jù),于是一時興起想利用Pyecharts在繪制的地圖上,浮動信息欄里顯示包含該國面積、人口等等更多的信息。一番折騰下來發(fā)現(xiàn)個有意思的問題。
首先想到的是直接將國土面積、國旗等,構建了['國家名稱', 人口數(shù), 國土面積, 國旗png文件地址]的列表(如下圖所示為人口數(shù)前十的國家的相應數(shù)據(jù))。將這個列表傳入Map()命令的datapair參數(shù),但發(fā)現(xiàn)程序報錯:
ValueError: too many values to unpack (expected 2)

ValueError: too many values to unpack (expected 2)
按照返回的信息,認為pyecharts是默認傳入的數(shù)據(jù)是一個[{"name": "value"}]二值對列表。于是將列表改寫為了['國家名稱', [人口數(shù), 國土面積, 國旗地址] ]的形式。這次pyecharts倒是生成了世界地圖,但并沒有按照人口數(shù)值進行著色,但從浮動顯示框的信息來看,各國的數(shù)據(jù)是正確導入了的。

世界地圖多值列表無法正常顯示
代碼如下:
top10_data = [
['China', [1439323776, 9388211, 'cn.png']],
['India', [1380004385, 2973190, 'in.png']],
['United States', [331002651, 9147420, 'us.png']],
['Indonesia', [273523615, 1811570, 'id.png']],
['Pakistan', [220892340, 770880, 'pk.png']],
['Brazil', [212559417, 8358140, 'br.png']],
['Nigeria', [206139589, 910770, 'ng.png']],
['Bangladesh', [164689383, 130170, 'bd.png']],
['Russia', [145934462, 16376870, 'ru.png']],
['Mexico', [128932753, 1943950, 'mx.png']]
]
low, high = min(Population1_and_Area.head(10).Pop), max(Population1_and_Area.head(10).Pop)
mapformatter = """
function (params, ticket, callback) {
var result = '';
var xName = params.name;
var seriesName = params.seriesName;
var pop = params.data.value[0];
var area = params.data.value[1];
var flagurl = params.data.value[2];
var value = params.value;
result += '<img src="./flags-mini/'+ flagurl +'" height=20 /> ' + '<br/>';
result += 'Area: ' + area + '<br/>';
result += 'Population: ' + value ;
result += '<br/>';
console.log(params);
return result
}
"""
(
Map(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
.add("", data_pair=top10_data , maptype="world",
label_opts=opts.LabelOpts(is_show=False),
is_map_symbol_show=False)
.set_global_opts(visualmap_opts=opts.VisualMapOpts(max_=high, min_=low),
tooltip_opts=opts.TooltipOpts(is_show=True,formatter=JsCode(mapformatter)))
.render_notebook()
)
鬼使神差的想看看中國地圖是不是也一樣無法著色,于是利用NAME_MAP_DATA 字典,將Top10國家名稱映射為中國的十個省份:
NAME_MAP_DATA = {
'廣東': 'China',
'江蘇': 'India',
'山東': 'United States',
'遼寧': 'Indonesia',
'河北': 'Pakistan',
'河南': 'Brazil',
'浙江': 'Nigeria',
'四川': 'Bangladesh',
'湖北': 'Russia',
'湖南': 'Mexico'}
Pyecharts的Map()參數(shù)中有'name_map'一項,用來將數(shù)據(jù)的datapair 中的'name'與Pyecharts地圖文件中名稱相對應。
Map().add(
series_name="",
data_pair=top10_data,
maptype="china",
name_map=NAME_MAP_DATA,
label_opts=opts.LabelOpts(is_show=False),
is_map_symbol_show=False,
itemstyle_opts={
"normal": {"areaColor": "#323c48", "borderColor": "#404a59"},
"emphasis": {
"label": {"show": 2010},
"areaColor": "rgba(255,255,255, 0.5)",
},
}).set_global_opts(
title_opts=opts.TitleOpts(
title="各國人口Top10",
pos_left="center",
pos_top="top",
title_textstyle_opts=opts.TextStyleOpts(
font_size=15),
),
tooltip_opts=opts.TooltipOpts(
is_show=True,
formatter=JsCode(
"""
function (params, ticket, callback) {
console.log(params);
var result = '';
var xName = params.name;
var seriesName = params.seriesName;
var pop = params.data.value[0];
var area = params.data.value[1];
var flagurl = params.data.value[2];
var value = params.value;
result += xName + '<br/>';
result += '<img src="./flags-mini/'+ flagurl +'" height=10 /> ' + '<br/>';
result += 'Area: ' + area + '<br/>';
result += 'Population: ' + value ;
result += '<br/>';
return result
}
"""
),
),
visualmap_opts=opts.VisualMapOpts(
is_calculable=True,
dimension=0,
pos_left="10",
pos_top="center",
range_text=["High", "Low"],
range_color=["lightskyblue", "yellow", "orangered"],
textstyle_opts=opts.TextStyleOpts(color="#ddd"),
min_=min_data,
max_=max_data,
)).render_notebook()

中國地圖中可以正常顯示
運行的結果,在maptype="china", name_map=NAME_MAP_DATA時,居然能夠按照'value'列表中的第一項數(shù)據(jù)正確著色,且浮動信息欄中的數(shù)據(jù)也都是正確的。
搞不懂的時,一模一樣的數(shù)據(jù),為什么在繪制世界地圖maptype="world"時就行不通呢?換成比如廣東省的地圖同樣也可以,但就是在世界地圖時不行。不知道是不是個小bug,也許以后會修正過來也說不定呢。