來源: 張京 鏈接:
https://segmentfault.com/a/1190000010900212
在上一篇文章《用Python畫一個(gè)中國(guó)地圖》中,我們簡(jiǎn)單描述了一下如何用Python
快速畫出一個(gè)中國(guó)地圖的輪廓,似乎沒有什么實(shí)用價(jià)值,這一次我們用實(shí)際數(shù)據(jù)填充它,使它看上去更有意義。
上色
延續(xù)上一次的代碼,我們這次還是只增加5
行代碼:
from matplotlib.patches import Polygon
ax = plt.gca()
for nshape, seg in enumerate(m.states):
poly = Polygon(seg, facecolor='r')
ax.add_patch(poly)
在展示結(jié)果之前,稍微解釋一下。第2
行plt.gca
,函數(shù)名看上去很詭異,是因?yàn)?/span>Python
里大量使用了縮寫,這個(gè)gca
就是Get Current Axes
的縮寫,實(shí)際上就是要獲得當(dāng)前圖形的座標(biāo)軸。然后我們開始一個(gè)循環(huán),把圖形文件中各個(gè)省的多邊形取出來,給它一個(gè)顏色,在這里我們統(tǒng)一放上紅色,也就是Red
的縮寫r
,然后把這個(gè)多邊形放在我們圖形的座標(biāo)軸上,然后就得到了下圖:
糟糕,怎么能少了臺(tái)灣呢?在此鄭重聲明:臺(tái)灣是中華人民共和國(guó)不可分割的領(lǐng)土!加入臺(tái)灣的Shape
文件,然后循環(huán)一下:
m.readshapefile('TWN_adm_shp/TWN_adm0', 'taiwan', drawbounds=True)
for nshape, seg in enumerate(m.taiwan):
poly = Polygon(seg, facecolor='r')
ax.add_patch(poly)
好了,這下祖國(guó)山河一片紅,看上去正確多了。
接下來,你還可以把各個(gè)省的名字打出來看一下,具體代碼就不解釋了:
for shapedict in m.states_info:
statename = shapedict['NL_NAME_1']
p = statename.split('|')
if len(p) > 1:
s = p[1]
else:
s = p[0]
print(s)
for shapedict in m.taiwan_info:
s = shapedict['NAME_CHINE']
print(s)
結(jié)果如下:
安徽北京重慶福建福建福建...
數(shù)據(jù)
接下來我們?nèi)?guó)家統(tǒng)計(jì)局搞點(diǎn)數(shù)據(jù)(http://www.stats.gov.cn/tjsj/pcsj/rkpc/6rp/indexce.htm),第六次全國(guó)人口普查數(shù)據(jù)可以直接下載Excel
文件,略作修改,導(dǎo)出成csv
文件,用我們上一課講的方法,一句話讀取進(jìn)來:
df = pd.read_csv('chnpop.csv')
直接輸出,大概是下面這個(gè)樣子:
渲染
好了,數(shù)據(jù)也有了,我們終于要開始做一些激動(dòng)人心的事情了。我們希望根據(jù)各省人口的多少用深淺不同的顏色為各個(gè)省份染色,那么首先第一步,我們需要選擇一個(gè)調(diào)色板,也就是色彩映射表colormap
,為此,matplotlib
為你準(zhǔn)備了數(shù)不勝數(shù)的選擇,我們隨便選擇一款國(guó)旗色紅黃色調(diào)的吧:
cmap = plt.cm.YlOrRd
然后我們把每個(gè)省的數(shù)據(jù)映射到colormap
上:
colors[s] = cmap(np.sqrt((pop - vmin) / (vmax - vmin)))[:3]
最后,我們把各個(gè)省的顏色描在地圖上:
color = rgb2hex(colors[statenames[nshape]])poly = Polygon(seg, facecolor=color, edgecolor=color)
噠噠,我們的全國(guó)人口數(shù)量熱力圖就完成了!可以看到河南、四川、廣東、山東幾個(gè)省的顏色比較深,說明這幾個(gè)省的人口總數(shù)最多,而西藏顏色最淺,代表這里的人口總數(shù)最少。
這里只是簡(jiǎn)單地舉了一個(gè)例子,你還可以把各省的人口總數(shù)除以面積,得到人口密度數(shù)據(jù),你還可以把各省的經(jīng)濟(jì)總量畫在圖上,總之,有了這個(gè)入門的方法,一切就都簡(jiǎn)單了呢。
最后,附上完整的代碼供大家參考。
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
from matplotlib.colors import rgb2hex
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('CHN_adm_shp/CHN_adm1', 'states', drawbounds=True)
df = pd.read_csv('chnpop.csv')
df['省名'] = df.地區(qū).str[:2]
df.set_index('省名', inplace=True)
statenames=[]
colors={}
cmap = plt.cm.YlOrRd
vmax = 100000000
vmin = 3000000
for shapedict in m.states_info:
statename = shapedict['NL_NAME_1']
p = statename.split('|')
if len(p) > 1:
s = p[1]
else:
s = p[0]
s = s[:2]
if s == '黑龍':
s = '黑龍'
statenames.append(s)
pop = df['人口數(shù)'][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()
(完)
看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人
關(guān)注「Python那些事」,做全棧開發(fā)工程師
聯(lián)系客服