这两天在看Pandas库和Basemap库,刚好第34届奥数获奖名单公布,就用它来试试手,学习一下数据清洗和数据可视化,用python制作了金牌榜和总牌榜可视化地图。按省区市归类排序,金牌主要集中在上海-浙江、北京、广东-湖南-湖北、川渝区域。从图中可以得出的基本结论是:金牌数的分布和地区经济活跃度基本一致,由此可知越是经济社会发达地区,越是重视奥数的学习,在教育上越舍得投入。这和通常的观念是完全吻合的,也符合数学是有钱人的游戏这一看法。
这是金牌榜示意图,颜色越深奖牌数越多。中国台湾未参赛,故用绿色表示。
这是金银铜牌奖牌总数排行榜。中国台湾未参赛,故以绿色表示。
数据可视化代码如下:
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
from matplotlib.colors import rgb2hex
import pandas as pd
import numpy as np
plt.figure(figsize=(16,8))
m = Basemap(llcrnrlon=77, llcrnrlat=14, urcrnrlon=140, urcrnrlat=51, projection='lcc', lat_1=33, lat_2=45, lon_0=100)
#m.drawcoastlines()
#m.drawcountries(linewidth=1.5)
m.readshapefile('CHN_adm_shp/gadm36_CHN_1', 'states', drawbounds=True)
df = pd.read_table('data.txt',sep='\s+',names=["序号","省市","人数"])
df['省市'] = df.省市.str[:2]
df.set_index('省市', inplace=True)
statenames=[]
colors={}
cmap = plt.cm.YlOrRd
#cmap = plt.cm.Reds
vmax = 17 #总榜30
vmin = 0
for shapedict in m.states_info:
statename = shapedict['NL_NAME_1']
p = statename.split('|')
if len(p) > 1:
s = p[1]
else:
s = p[0]
s = s[:2]
if s == '黑龍':
s = '黑龙'
statenames.append(s)
pop = df['人数'][s]
colors[s] = cmap(np.sqrt((pop - vmin) / (vmax - vmin)))[:3]
ax = plt.gca()
for nshape, seg in enumerate(m.states):
color = rgb2hex(colors[statenames[nshape]])
poly = Polygon(seg, facecolor=color, edgecolor=color)
ax.add_patch(poly)
m.readshapefile('TWN_adm_shp/TWN_adm0', 'taiwan', drawbounds=True)
for nshape, seg in enumerate(m.taiwan):
poly = Polygon(seg, facecolor='g')
ax.add_patch(poly)
m.readshapefile('MAC_adm_shp/MAC_adm1', 'states', drawbounds=True)
m.readshapefile('HKG_adm_shp/HKG_adm0', 'xianggang', drawbounds=True)
for nshape, seg in enumerate(m.xianggang):
poly = Polygon(seg, facecolor='r')
ax.add_patch(poly)
plt.show()
后续,需要对数据作进一步的清洗,作一份奖牌的城市分布散点图,应该更能说明问题。
领取专属 10元无门槛券
私享最新 技术干货