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)
我正在尝试生成按某些值着色的世界国家地图,但生成的地图中缺少某些国家/地区。这是我的代码:
获取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)