前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小蛇学python(23)basemap入门与进阶

小蛇学python(23)basemap入门与进阶

作者头像
用户2145057
发布2020-02-18 15:20:53
9330
发布2020-02-18 15:20:53
举报

Basemap是matplotlib下的一个库文件,专门应用于绘制地图。这一节就来详细讲解该文件的使用。首先来绘制一个最简单的地图。代码结果如图1所示。

代码语言:javascript
复制
from mpl_toolkits.basemap import Basemap
map = Basemap() #实例化一个对象 map.drawcoastlines() #map调用函数,该函数内置世界地图海岸线
plt.savefig('image_name',bbox_inches='tight')       #去掉图片边缘空白区域 plt.show()

图1

如果觉得这样的地图过于单调,还可以给地图涂色。如图2所示。

代码语言:javascript
复制
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()

图2

你也许觉得这样的世界地图有些变形,这是因为投影方式的不同,Basemap内置了24种投影方式,感兴趣的读者可以浏览Basemap手册仔细了解,本书不在这些细节上做过多牵扯。

当你不显式指定投影方式时,Basemap会默认上图的投影方式,这也是绘制世界地图普遍采用的投影方式。其特点就是越接近赤道的地区越真实,维度越高的地区越失真,看起来比真实情况要小。

当你并不想绘制世界地图时,可以根据显式指定上下纬度以及左右经度确定具体区域。

代码语言:javascript
复制
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所示

图3

如果想进一步完成绘制中国地图的工作,添加上中国各省份的边界,这时候需要下载特定的数据文件。因为Basemap是外国人开发的库,因此并没有内置中国各省份的边界数据。

不过从https://gadm.org/download_country_v3.html中,可以下载到你想要的任何国家的省份边界数据。如图4所示。

代码语言:javascript
复制
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()

图4

有了以上的基础,接下来实现一个实例。利用之前的中国各省份GDP的数据文件,结合Basemap画一幅GDP热力图。代码如下,效果如图5所示。

代码语言:javascript
复制
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()

图5

关键步骤已经写了代码注释,不过还是从整体逻辑角度解释一下代码。

(1)设置展示地图区域的经纬度参数。

(2)读取内含中国大陆省份边界的数据文件,需要注意这些数据文件也是海外人士提供的,因为某些原因缺少中国台湾的数据,所以在后期把中国台湾的相关数据也补充添加进去了。

(3)读取中国各省份GDP数据,并将地区列设置为索引。

(4)比较关键,代码量也比较多,其完成了处理shapefile格式数据,设置色彩映射的功能。

(5)是进行色彩填充,以省份行政区域为单位进行循环,依次填充各省份GDP所对应的颜色。GDP越高,颜色越深。

最后案例对应数据可点赞后简信我索取。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档