这篇文章给出了如何绘制中国人口密度图,但是运行存在一些问题,我在一些地方进行了修改。
本人使用的IDE是anaconda,因此事先在anaconda prompt 中安装Basemap包
1
|
conda install Basemap |
新建文档,导入需要的包
1
2
3
4
5
6
|
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中不包括中国省界,需要在下面网站下载中国省界,点击Shapefile下载。
生成中国大陆省界图片。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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 ) |
去国家统计局网站下载人口各省,只需保留地区和总人口即可,保存为csv格式并改名为pop.csv。
读取数据,储存为dataframe格式,删去地名之中的空格,并设置地名为dataframe的index。
1
2
3
4
5
6
7
8
9
10
|
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文件中的地名并不完全一样,需要进行一些处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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 ] |
最后画出图片即可
1
2
3
4
5
6
7
|
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() |
完整代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# -*- 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() |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_41816368/article/details/80787415