Python:散景未按预期生成世界国家地图

Python: bokeh not generating world's countries map as expected

我正在尝试生成按某些值着色的世界国家地图,但生成的地图中缺少某些国家/地区。这是我的代码:

获取geojson数据

import urllib
url = 'https://raw.githubusercontent.com/datasets/geo-boundaries-world-110m/master/countries.geojson'
testfile = urllib.URLopener()
if os.path.exists('countries.json'):
    print "file already exists"
else:
    testfile.retrieve(url, "countries.json")

使用散景生成地图

import json,pandas
from collections import OrderedDict
from bokeh.plotting import figure, show, output_file, ColumnDataSource
from bokeh.models import HoverTool
user_by_country_count = pandas.read_csv('data.csv')

with open('countries.json','r') as f:
    geodata = json.load(f)
f.close()
geodata_features = geodata['features']
country_xs = []
country_ys = []
country_names = []
country_num_users = []
country_colors = []
colors = ['#CCE5FF','#CCCCFF','#9999FF','#6666FF','#3333FF',
         '#0000FF','#0000CC','#000099','#000066','#0000CC']

for aCountry in geodata_features:
    coords = aCountry['geometry']['coordinates'][0]
    country_xs.append(map(lambda x:x[0],coords))
    country_ys.append(map(lambda x:x[1],coords))
    cName = aCountry['properties']['name']
    country_names.append(cName)
    if cName in user_by_country_count['Country'].values:            
        num_users = user_by_country_count['Count'][user_by_country_count[user_by_country_count.Country==cName].index[0]]
        country_num_users.append(num_users)
        country_colors.append(colors[int(np.log(num_users))])
    else:
        country_num_users.append(0)
        country_colors.append("#00FF80")
source = ColumnDataSource(
    data = dict(
        x=country_xs,
        y=country_ys,
        color=country_colors,
        name=country_names,
        users=country_num_users,
    )
)
output_file("global.html", title="global.py example")
TOOLS="pan,wheel_zoom,box_zoom,reset,hover,save"
p = figure(title="Upwork Users Location", tools=TOOLS)
p.patches('x', 'y',
    fill_color='color', fill_alpha=0.7,
    line_color="white", line_width=0.5,
    source=source)
hover = p.select(dict(type=HoverTool))
hover.point_policy = "follow_mouse"
hover.tooltips = OrderedDict([
    ("Name", "@name"),
    ("Number of Users", "@users"),
])
show(p)

我怀疑问题可能出在 geojson 数据中。当我仔细观察时,看起来有些坐标是作为数字列表给出的,而另一些坐标是作为数字列表给出的。但是这个geojson之前被很多人用过所以我想知道是否有其他人遇到过类似的问题。

阿根廷和其他一些国家属于MultiPolygon类型,例如巴西属于Polygon类型。拥有岛屿或独立土地的国家属于 MultiPolygon 类型。所以 MultiPolygon 的坐标应该包含更多一级数组,你应该处理它:

#!/usr/bin/python2
import json,pandas
from collections import OrderedDict
from bokeh.plotting import figure, show, output_file, ColumnDataSource
from bokeh.models import HoverTool
import math
user_by_country_count = pandas.read_csv('data.csv')

with open('countries.json','r') as f:
    geodata = json.load(f)

geodata_features = geodata['features']
country_xs = []
country_ys = []
country_names = []
country_num_users = []
country_colors = []
colors = ['#CCE5FF','#CCCCFF','#9999FF','#6666FF','#3333FF',
         '#0000FF','#0000CC','#000099','#000066','#0000CC']

for aCountry in geodata_features:
    cName = aCountry['properties']['name']
    country_names.append(cName)

    geometry_type = aCountry['geometry']['type']
    if geometry_type == "MultiPolygon":
        for poly_coords in aCountry['geometry']['coordinates']:
            coords = poly_coords[0]

            country_xs.append(map(lambda x:x[0],coords))
            country_ys.append(map(lambda x:x[1],coords))
    else:
        coords = aCountry['geometry']['coordinates'][0]
        country_xs.append(map(lambda x:x[0],coords))
        country_ys.append(map(lambda x:x[1],coords))

    if cName in user_by_country_count['Country'].values:
        num_users = user_by_country_count['Count'][user_by_country_count[user_by_country_count.Country==cName].index[0]]
        country_num_users.append(num_users)
        country_colors.append(colors[int(math.log(num_users))])
    else:
        country_num_users.append(0)
        country_colors.append("#00FF80")

source = ColumnDataSource(
    data = dict(
        x=country_xs,
        y=country_ys,
        color=country_colors,
        name=country_names,
        users=country_num_users,
    )
)
output_file("global.html", title="global.py example")
TOOLS="pan,wheel_zoom,box_zoom,reset,hover,save"
p = figure(title="Upwork Users Location", tools=TOOLS)
p.patches('x', 'y',
    fill_color='color', fill_alpha=0.7,
    line_color="white", line_width=0.5,
    source=source)
hover = p.select(dict(type=HoverTool))
hover.point_policy = "follow_mouse"
hover.tooltips = OrderedDict([
    ("Name", "@name"),
    ("Number of Users", "@users"),
])
show(p)