Basemap是matplotlib下的一个库文件,专门应用于绘制地图。这一节就来详细讲解该文件的使用。首先来绘制一个最简单的地图。代码结果如图1所示。
from mpl_toolkits.basemap import Basemap
map = Basemap() #实例化一个对象 map.drawcoastlines() #map调用函数,该函数内置世界地图海岸线
plt.savefig('image_name',bbox_inches='tight') #去掉图片边缘空白区域 plt.show()
如果觉得这样的地图过于单调,还可以给地图涂色。如图2所示。
from mpl_toolkits.basemap import Basemap
map = Basemap()
map.drawmapboundary(fill_color = 'aqua') #将整个地图涂上蓝色的一层 map.fillcontinents(color = 'coral') #将大陆部分涂上黄色 map.drawcoastlines()
plt.savefig('image_name',bbox_inches='tight')
plt.show()
你也许觉得这样的世界地图有些变形,这是因为投影方式的不同,Basemap内置了24种投影方式,感兴趣的读者可以浏览Basemap手册仔细了解,本书不在这些细节上做过多牵扯。
当你不显式指定投影方式时,Basemap会默认上图的投影方式,这也是绘制世界地图普遍采用的投影方式。其特点就是越接近赤道的地区越真实,维度越高的地区越失真,看起来比真实情况要小。
当你并不想绘制世界地图时,可以根据显式指定上下纬度以及左右经度确定具体区域。
map = Basemap(llcrnrlon=73, llcrnrlat=18, urcrnrlon=135, urcrnrlat=55, resolution='i',
projection='merc', lat_0=42.5, lon_0=120) #通过经纬度确定中国区域 map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='coral')
map.drawcoastlines()
map.drawcountries() #画出国家边界
plt.savefig('image_name', bbox_inches='tight')
plt.show()
一副漂亮的中国地图就画出来了。还添加了国家的边界,也是一句代码就可以完成的工作。如图3所示
如果想进一步完成绘制中国地图的工作,添加上中国各省份的边界,这时候需要下载特定的数据文件。因为Basemap是外国人开发的库,因此并没有内置中国各省份的边界数据。
不过从https://gadm.org/download_country_v3.html中,可以下载到你想要的任何国家的省份边界数据。如图4所示。
map = Basemap(llcrnrlon=73, llcrnrlat=18, urcrnrlon=135, urcrnrlat=55, resolution='i',
projection='merc', lat_0=42.5, lon_0=120)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='coral')
map.drawcoastlines()
map.drawcountries()
map.readshapefile('gadm36_CHN_1', 'states', drawbounds=True) #读取各省边界数据 plt.savefig('image_name', bbox_inches='tight')
plt.show()
有了以上的基础,接下来实现一个实例。利用之前的中国各省份GDP的数据文件,结合Basemap画一幅GDP热力图。代码如下,效果如图5所示。
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
from matplotlib.colors import rgb2hex
plt.figure(figsize=(16, 8))
map=Basemap(llcrnrlon=77,llcrnrlat=14,urcrnrlon=140,urcrnrlat=51,projection='lcc',lat_1=33,lat_2=45,lon_0=100)
map.drawcountries(linewidth=1.5)
map.drawcoastlines()
map.readshapefile('gadm36_CHN_1', 'states', drawbounds=True) #读取省份边界数据 df = pd.read_csv('Chinese_GDP.csv') #读取GDP数据 df.set_index('地区', inplace=True) #将列名为地区这一列设为索引 provinces = map.states_info #读取省份信息 statenames = []
colors = {}
cmap = plt.cm.YlOrRd #指定色彩映射种类 GDP_max = max(df['2016年'])
GDP_min = min(df['2016年'])
for each_province in provinces: #for循环中是对shapefile格式数据的处理,与主要程序逻辑无关 province_name = each_province['NL_NAME_1']
p = province_name.split('|')
if len(p) > 1:
s = p[1]
else:
s = p[0]
s = s[:2]
if s == '黑龍':
s = '黑龙江'
if s == '内蒙':
s = '内蒙古'
statenames.append(s)
GDP = df['2016年'][s]
colors[s] = cmap(np.sqrt((GDP - GDP_min) / (GDP_max - GDP_min)))[:3] #构建色彩映射关系 statenames.append('Taiwan') #将台湾的数据单独添加进去 GDP_Taiwan = df['2016年']['Taiwan']
colors['Taiwam'] = cmap(np.sqrt((GDP_Taiwan - GDP_min) / (GDP_max - GDP_min)))[:3]
ax = plt.gca()
for nshape, seg in enumerate(map.states):
color = rgb2hex(colors[statenames[nshape]]) #将RGB色彩转为HEX色彩 poly = Polygon(seg, facecolor=color, edgecolor=color) #将每个省份对应的颜色进行填充 ax.add_patch(poly)
map.readshapefile('gadm36_TWN_0', 'states', drawbounds=True)
for nshape, seg in enumerate(map.states):
color = rgb2hex(colors[statenames[nshape]]) #将RGB色彩转为HEX色彩 poly = Polygon(seg, facecolor=color, edgecolor=color) #将每个省份对应的颜色进行填充 ax.add_patch(poly)
ax.set_title('China GDP heatmap')
plt.savefig('image_name', bbox_inches='tight')
plt.show()
关键步骤已经写了代码注释,不过还是从整体逻辑角度解释一下代码。
(1)设置展示地图区域的经纬度参数。
(2)读取内含中国大陆省份边界的数据文件,需要注意这些数据文件也是海外人士提供的,因为某些原因缺少台湾的数据,所以在后期把台湾的相关数据也补充添加进去了。
(3)读取中国各省份GDP数据,并将地区列设置为索引。
(4)比较关键,代码量也比较多,其完成了处理shapefile格式数据,设置色彩映射的功能。
(5)是进行色彩填充,以省份行政区域为单位进行循环,依次填充各省份GDP所对应的颜色。GDP越高,颜色越深。
最后案例对应数据可点赞后简信我索取。