在学习了之一的基础上,我们来继续深入学习一些Basemap绘图知识:
我们学会了绘制中国地图,能否运用相关知识来绘制美国地图呢?
首先确定以下几点知识:
美国本土:纬度:北纬25度-北纬49度;经度:西经70度~西经130度,东经正数,西经为负数;北纬为正数,南纬为负数。
Basemap的部分参数:
llcrnrlon - lower left corner lon的缩写 (地图左下角的经度)
llcrnrlat - lower left corner lat的缩写 (地图左下角的纬度)
urcrnrlon - upper right corner lon的缩写 (地图右上角的经度)
urcrnrlat - upper right corner lat的缩写 (地图右下角的纬度)
projection='lcc’为双标准纬线等角正轴圆锥投影,也称兰伯特正形圆锥 (Lambert Conformal Conic, LCC) 投影。该投影的微分圆投影后仍为圆形。经线为辐射直线,纬线为同心圆圆弧。沿指定的两条标准纬度线和无长度变形,常用来编制中、小比例尺地图。一般我们绘制这种平面地图都使用lcc投影,上方的其他很多投影是在地理、气象相关学科中才会使用。
lcc投影需指定两条标准纬度线lat1, lat2,如中国常用的lcc投影标准纬度线为B1=25º,B2=45º或B1=33º,B2=45º
每幅图内两条标准纬线的纬度:
Q1=QS+4分 (南纬度) Q2=QN-4分(北纬度)
绘制美国地图代码:
from mpl_toolkits.basemap import Basemap #导入Basemap
import matplotlib.pyplot as plt #导入 matplotlib.pyplot
fig=plt.figure(figsize=(16, 8)) #表示figure 的大小为宽、长(单位为英寸)
#lat_1:南纬度+4,lat_2=北纬度-4,lon_0=-100,设定经度的中心
m= Basemap(llcrnrlon=-130, llcrnrlat=20, urcrnrlon=-65, urcrnrlat=49,projection='lcc',lat_1=24, lat_2=45, lon_0=-100)
m.drawcountries(linewidth=1.5) # 开始画上国家
m.drawcoastlines() #把海岸线画上
m.drawmapboundary(fill_color = 'blue')# 首先给地球涂上蓝色的一层
m.drawstates() # 绘制州,美国默认有,但中国地图不行
m.drawcounties() # 绘制县,这里好象没有县的划分。
m.fillcontinents(color = 'yellow', lake_color = 'aqua')# 再给大陆涂上黄色,给江河湖泊涂上水蓝的颜色
plt.show()
fig.savefig('../test/America.jpg',dpi=600)
#保存地图到根目录下的test文件夹,如我在D:/pythontest中运行jupyter notebook,
#则地图会保存到D:/pythontest/test文件夹中,请确保先建有该文件夹
Basemap缺省的包里没有中国的省区,只有美国的州,毕竟是美国人做的嘛。不过好在世界很大,有专门的国际组织干这事,在这里(https://gadm.org/download_country_v3.html)你可以下载全世界任何一个国家的行政区划Shape文件,然后我们给它加上:
这里我们country选择China,下载对应的Shapefile文件
m.readshapefile(’…/gadm36_CHN_shp/gadm36_CHN_1’, ‘states’, drawbounds=True)
具体代码如下:
from mpl_toolkits.basemap import Basemap #导入Basemap
import matplotlib.pyplot as plt #导入 matplotlib.pyplot
from matplotlib.patches import Polygon
#import numpy as np #导入 numpy
fig=plt.figure(figsize=(16, 8)) #表示figure 的大小为宽、长(单位为英寸)
m= Basemap(llcrnrlon=77, llcrnrlat=14, urcrnrlon=140, urcrnrlat=51, projection='lcc', lat_1=33, lat_2=45, lon_0=100)
#m= Basemap(llcrnrlon=73, llcrnrlat=18, urcrnrlon=135, urcrnrlat=53)
m.drawcountries(linewidth=1.5)
m.drawcoastlines()
m.drawmapboundary(fill_color = 'blue')
m.fillcontinents(color = 'yellow', lake_color = 'aqua')
#说明:这里需要注意下载的Shapefile文件存放位置,我运行根目录下的gadm36_CHN_shp文件夹里的gadm36_CHN_1.shp
#gadm36_CHN_0 国界,gadm36_CHN_1:中国省界,gadm36_CHN_2:中国市界,gadm36_CHN_3:中国县界
m.readshapefile('../gadm36_CHN_shp/gadm36_CHN_1', 'states', drawbounds=True)
plt.show()
然后就得到了下图:
给中国地图变成红色
ax = plt.gca() #gca就是Get Current Axes的缩写,实际上就是要获得当前图形的座标轴。
#开始一个循环,把图形文件中各个省的多边形取出来,给它一个颜色,在这里我们统一放上红色,也就是Red的缩写r
for nshape, seg in enumerate(m.states):
poly = Polygon(seg, facecolor=‘r’)
ax.add_patch(poly) #把这个多边形放在我们图形的座标轴上
完整代码如下:
#给中国地图上色
from mpl_toolkits.basemap import Basemap #导入Basemap
import matplotlib.pyplot as plt #导入 matplotlib.pyplot
from matplotlib.patches import Polygon
#import numpy as np #导入 numpy
fig=plt.figure(figsize=(16, 8)) #表示figure 的大小为宽、长(单位为英寸)
m= Basemap(llcrnrlon=77, llcrnrlat=14, urcrnrlon=140, urcrnrlat=51, projection='lcc', lat_1=33, lat_2=45, lon_0=100)
#m= Basemap(llcrnrlon=73, llcrnrlat=18, urcrnrlon=135, urcrnrlat=53)
m.drawcountries(linewidth=1.5)
m.drawcoastlines()
m.drawmapboundary(fill_color = 'blue')
m.fillcontinents(color = 'yellow', lake_color = 'aqua')
#说明:这里需要注意下载的Shapefile文件存放位置,我运行根目录下的gadm36_CHN_shp文件夹里的gadm36_CHN_1.shp
#gadm36_CHN_0 国界,gadm36_CHN_1:中国省界,gadm36_CHN_2:中国市界,gadm36_CHN_3:中国县界
m.readshapefile('../gadm36_CHN_shp/gadm36_CHN_1', 'states', drawbounds=True)
ax = plt.gca() #gca就是Get Current Axes的缩写,实际上就是要获得当前图形的座标轴。
#开始一个循环,把图形文件中各个省的多边形取出来,给它一个颜色,在这里我们统一放上红色,也就是Red的缩写r
for nshape, seg in enumerate(m.states):
poly = Polygon(seg, facecolor='r')
ax.add_patch(poly) #把这个多边形放在我们图形的座标轴上
plt.show()
老外没给我们加入台湾地区到中国,这里我们给中国地图增加台湾地区,前提,同样方法下载Taiwan的Shapefile文件
增加台湾代码如下:
#增加台湾地区
m.readshapefile('../gadm36_TWN_shp/gadm36_TWN_1', 'taiwan', drawbounds=True)
for nshape, seg in enumerate(m.taiwan):
poly = Polygon(seg, facecolor='r')
ax.add_patch(poly)
#增加台湾地区结束
国家统计局下载第六次全国人口普查数据
(http://www.stats.gov.cn/tjsj/pcsj/rkpc/6rp/indexce.htm),第六次全国人口普查数据可以直接下载Excel文件,略作修改,这里下载第一个:各地区户数,人口数和性别比,并修改为第一行为字段名,去除多余信息(重点保留地区和各地区的人口数),导出成xlsx文件,读取效果如图:
from pandas import read_excel
df=pd.read_excel('各地区户数人口数和性别比.xlsx')
df
我们希望根据各省人口的多少用深浅不同的颜色为各个省份染色,那么首先第一步,我们需要选择一个调色板,也就是色彩映射表colormap,为此,matplotlib为你准备了数不胜数的选择,我们随便选择一款国旗色红黄色调的吧: cmap = plt.cm.YlOrRd
然后我们把每个省的数据映射到colormap上:
colors[s] = cmap(np.sqrt((pop - vmin) / (vmax - vmin)))[:3]
最后,我们把各个省的颜色描在地图上:
color = rgb2hex(colors[statenames[nshape]])poly = Polygon(seg, facecolor=color, edgecolor=color)
完整代码如下:
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
from matplotlib.colors import rgb2hex
import numpy as np
import pandas as pd
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.drawcountries(linewidth=1.5)
m.drawcoastlines()
m.readshapefile('../gadm36_CHN_shp/gadm36_CHN_1', 'states', drawbounds=True)
df=pd.read_excel('各地区户数人口数和性别比.xlsx')
new_index_list = []
for i in df["地区"]:
i = i.replace(" ","")
new_index_list.append(i)
new_index = {"region": new_index_list}
new_index = pd.DataFrame(new_index)
df = pd.concat([df,new_index], axis=1)
df = df.drop(["地区"], axis=1)
df.set_index("region", inplace=True)
provinces = m.states_info
statenames=[]
colors = {}
cmap = plt.cm.YlOrRd
vmax = 100000000
vmin = 3000000
for each_province in provinces:
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)
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('../gadm36_TWN_shp/gadm36_TWN_1', 'taiwan', drawbounds=True)
for nshape, seg in enumerate(m.taiwan):
poly = Polygon(seg, facecolor='r')
ax.add_patch(poly)
#增加台湾地区结束
plt.show()
本文涉及的源代码及各地区人口分布文件,中国和台湾行政区划Shape文件,如果不能按文中的下载到,可从我提供的资源下载。https://download.csdn.net/download/qq_26665293/12253996