python实际应用6-用basemap 绘制中国地图
@2019年3月30日
-
背景
工作中有时会获得分省的一些数据,一直希望能以地图方式显示数据。之前,有个谷歌的三方库,但因为被墙无法使用。最近借一个小任务,搜集了31省的网速,希望用地图显示。这次在网上发现了basemap这个三方库。 -
准备工作
【文档】
basemap 官方教程见 https://basemaptutorial.readthedocs.io/en/latest/index.html,这里只是简单应用。
【三方库】
安装还是挺麻烦的,官方文档:http://matplotlib.org/basemap/users/installing.html,简单介绍如下:
需按如下顺序安装三方库。
1.pyproj
2.geos
pip install geos
3.matplotlib
4.basemap (base on geos)
https://www.lfd.uci.edu/~gohlke/pythonlibs/#basemap
pip install basemap-1.2.0-cp36-cp36m-win32.whl (我是32位系统)
5.下载 shapefile of china
https://gadm.org/download_country_v3.html
中国需下载 gadm36_CHN_shp、gadm36_HKG_shp、gadm36_TWN_shp。【数据准备】
31省网速数据格式如下,lon 为经度, lat为维度。 -
Python 程序
【程序】如下
# draw_map_Net_test.py
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
import pandas as pd
plt.figure(figsize=(16,8))
m = Basemap(llcrnrlon=80, llcrnrlat=14, urcrnrlon=138, urcrnrlat=51, projection='lcc', lat_1=33, lat_2=45, lon_0=100
,resolution='c'
,area_thresh=10000000
) # 兰勃特投影
# The resolution options are c (crude, the default), l (low), i (intermediate), h (high), f (full) or None
#Fill the globe with a blue color1
m.drawmapboundary(fill_color= 'aqua')
#Fill the continents with the land color
#m.fillcontinents(color='coral',lake_color='aqua')
m.fillcontinents(color='gray',lake_color="#7777ff")
m.drawcountries(linewidth=1,color='gray') # 隐藏国境线
#m.drawcoastlines()
m.readshapefile('gadm36_CHN_shp/gadm36_CHN_1', 'states', drawbounds=True)
m.readshapefile('gadm36_TWN_shp/gadm36_TWN_0', 'taiwan', drawbounds=True)
m.readshapefile('gadm36_HKG_shp/gadm36_HKG_0', 'hongkong', drawbounds=True)
df = pd.read_csv('D://30省测试结果//30省网速测试结果.csv' , encoding='gbk')
#print(df)
df['地区'] = df.省名.str[:2]
df.set_index('地区', inplace=True)
statenames=[]
colors={}
cmap = plt.cm.YlOrRd
vmax = 10
vmin = 4
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]
lons = df['lon'][s]
lats = df['lat'][s]
x, y = m(lons, lats)
#plt.text(x, y, pop, fontsize=12, fontweight='bold',
# ha='left', va='bottom', color='k')
plt.text(x, y,'%.1f' % pop, fontsize=10,
ha='center', va='center', color='b')
if pop >=10 :
colors[s]= "#00bfff" #'cyan'
elif pop >5 and pop <10 :
colors[s] = "#40ff00" #'olive'
elif pop ==5:
colors[s] = "#aaff00" #'olive'
elif pop >=3 and pop <5 :
colors[s] ="#e5e600" #'yellow'
elif pop >=1 and pop <3:
colors[s]='orange'
elif pop >0 and pop <1:
colors[s] = "#ff8000" #'red'
else:
colors[s] = "red"
ax1 = plt.gca()
for nshape, seg in enumerate(m.states):
#color = rgb2hex(colors[statenames[nshape]])
color=colors[statenames[nshape]]
poly = Polygon(seg, facecolor=color, edgecolor=color)
ax1.add_patch(poly)
for nshape, seg in enumerate(m.taiwan):
poly = Polygon(seg, facecolor="#8e2424") #'brown'
ax1.add_patch(poly)
for nshape, seg in enumerate(m.hongkong):
poly = Polygon(seg, facecolor='brown')
ax1.add_patch(poly)
#----------------------------------------------------------------------------------
plt.show()
- 效果
这张图实际为依据优化前网速绘制,也未隐藏国境线。