https://mp.weixin.qq.com/s/Bh-L3syzJSHhLPZqzHvIyA
这篇文章给出了如何绘制中国人口密度图,但是运行存在一些问题,我在一些地方进行了修改。
本人使用的IDE是anaconda,因此事先在anaconda prompt 中安装Basemap包
conda install Basemap
新建文档,导入需要的包
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
Basemap中不包括中国省界,需要在下面网站下载中国省界(https://gadm.org/download_country_v3.html),点击Shapefile下载。
生成中国大陆省界图片。
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)
去国家统计局网站下载人口各省(http://www.stats.gov.cn/tjsj/pcsj/rkpc/6rp/indexce.htm),只需保留地区和总人口即可,保存为csv格式并改名为pop.csv。
读取数据,储存为dataframe格式,删去地名之中的空格,并设置地名为dataframe的index。
df = pd.read_csv('pop.csv')
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)
将Basemap中的地区与我们下载的csv中的人口数据对应起来,建立字典。注意,Basemap中的地名与csv文件中的地名并不完全一样,需要进行一些处理。
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)
plt.show()
完整代码如下
# -*- coding: utf-8 -*-
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_csv('pop.csv')
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)
plt.show()