Python使用 matplotlib的basemap绘图之二--画美国地图和中国人口热力图(含省份)

在学习了之一的基础上,我们来继续深入学习一些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文件夹中,请确保先建有该文件夹

效果如下图:
Python使用 matplotlib的basemap绘图之二--画美国地图和中国人口热力图(含省份)_第1张图片

画出中国含省份边界的地图

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()

然后就得到了下图:
Python使用 matplotlib的basemap绘图之二--画美国地图和中国人口热力图(含省份)_第2张图片
给中国地图变成红色
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)
#增加台湾地区结束

效果如图:
Python使用 matplotlib的basemap绘图之二--画美国地图和中国人口热力图(含省份)_第3张图片

绘制人口热力图

国家统计局下载第六次全国人口普查数据

(http://www.stats.gov.cn/tjsj/pcsj/rkpc/6rp/indexce.htm),第六次全国人口普查数据可以直接下载Excel文件,略作修改,这里下载第一个:各地区户数,人口数和性别比,并修改为第一行为字段名,去除多余信息(重点保留地区和各地区的人口数),导出成xlsx文件,读取效果如图:

from pandas import read_excel
df=pd.read_excel('各地区户数人口数和性别比.xlsx')
df

Python使用 matplotlib的basemap绘图之二--画美国地图和中国人口热力图(含省份)_第4张图片
我们希望根据各省人口的多少用深浅不同的颜色为各个省份染色,那么首先第一步,我们需要选择一个调色板,也就是色彩映射表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()

Python使用 matplotlib的basemap绘图之二--画美国地图和中国人口热力图(含省份)_第5张图片

本文涉及的源代码及各地区人口分布文件,中国和台湾行政区划Shape文件,如果不能按文中的下载到,可从我提供的资源下载。https://download.csdn.net/download/qq_26665293/12253996

你可能感兴趣的:(Python)