繪圖: matplotlib Basemap簡介


作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝!

 

在數據可視化過程中,我們常常需要將數據根據其采集的地理位置在地圖上顯示出來。比如說我們會想要在地圖上畫出城市,飛機的航線,乃至於軍事基地等等。通常來說,一個地理信息系統都會帶有這樣的功能。今天我們討論如何在Python上實現,並且使用免費的工具包。

 

matplotlib是Python常用的數據繪制包。它基於numpy的數組運算功能。matplotlib繪圖功能強大,可以輕易的畫出各種統計圖形,比如散點圖,條行圖,餅圖等。matplotlib常與numpy和scipy相配合,用於許多研究領域。他們是免費工具,但其功能足可以與科研界的大佬Matlab競爭。

Basemap是Matplotlib的一個子包,負責地圖繪制。在數據可視化過程中,我們常需要將數據在地圖上畫出來。比如說我們在地圖上畫出城市人口,飛機航線,軍事基地,礦藏分布等等。這樣的地理繪圖有助於讀者理解空間相關的信息。

 

我們下面用Basemap畫出亞洲主要城市的人口。如下圖,人口的數量用圓圈的大小表示:

數據如下(我從Wikipedia上整理的,你可以隨意使用)。將數據保存在文件major_city:

Shanghai 23019148  31.23N  121.47E  China
Mumbai   12478447  18.96N  72.82E   India
Karachi  13050000  24.86N  67.01E   Pakistan
Delhi    16314838  28.67N  77.21E   India
Manila   11855975  14.62N  120.97E  Philippines
Seoul    23616000  37.56N  126.99E  Korea(South)
Jakarta  28019545   6.18S  106.83E  Indonesia
Tokyo    35682460  35.67N  139.77E  Japan
Peking   19612368  39.91N  116.39E  China

第一列是城市名,第二列是人口,第三第四列為緯度和經度,最后一列為所在國家。

 

下面是我的Python代碼,用以繪制上面的地圖:

View Code
# Written by Vamei, http://www.cnblogs.com/vamei/ # Feel free to use or modify this script.

from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt import numpy as np #============================================# read data
names = [] pops = [] lats = [] lons = [] countries = [] for line in file("../data/major_city"): info = line.split() names.append(info[0]) pops.append(float(info[1])) lat = float(info[2][:-1]) if info[2][-1] == 'S': lat = -lat lats.append(lat) lon = float(info[3][:-1]) if info[3][-1] == 'W': lon = -lon + 360.0 lons.append(lon) country = info[4] countries.append(country) #============================================ # set up map projection with # use low resolution coastlines.
map = Basemap(projection='ortho',lat_0=35,lon_0=120,resolution='l') # draw coastlines, country boundaries, fill continents.
map.drawcoastlines(linewidth=0.25) map.drawcountries(linewidth=0.25) # draw the edge of the map projection region (the projection limb)
map.drawmapboundary(fill_color='#689CD2') # draw lat/lon grid lines every 30 degrees.
map.drawmeridians(np.arange(0,360,30)) map.drawparallels(np.arange(-90,90,30)) # Fill continent wit a different color
map.fillcontinents(color='#BF9E30',lake_color='#689CD2',zorder=0) # compute native map projection coordinates of lat/lon grid.
x, y = map(lons, lats) max_pop = max(pops) # Plot each city in a loop. # Set some parameters
size_factor = 80.0 y_offset = 15.0 rotation = 30
for i,j,k,name in zip(x,y,pops,names): size = size_factor*k/max_pop cs = map.scatter(i,j,s=size,marker='o',color='#FF5600') plt.text(i,j+y_offset,name,rotation=rotation,fontsize=10) plt.title('Major Cities in Asia & Population') plt.show()


程序分為兩個部分,第一部分為從文件讀取數據並處理。第二部分才是真正用basemap繪圖。

 

地圖的大小、投影方法等重要信息,是在Basemap()的調用中實現的:

map = Basemap(projection='ortho',lat_0=35,lon_0=120,resolution='l')

projection參數規定了投影方法。改變投影方法,繪圖結果也將非常不同。

 

城市所在位置是經緯度。我們想要把經緯度對應圖像的像素點,需要轉換:

x, y = map(lons, lats)

這個語句轉換為圖像上的位置。

 

最后,調用繪制散點圖的方法scatter():

cs = map.scatter(i,j,s=size,marker='o',color='#FF5600')

在地圖上畫出數據。

 

總結

matplotlib中的Basemap是很好用的,具有專業標准的地圖繪制工具。它可以與matplotlib的一般繪圖功能結合,在地圖上繪制數據。

 

文中需要的軟件包:

numpy, matplotlib, mpl_toolkits

可以使用pip來下載安裝各個包。

 

在Ubuntu的repository中,你可以找到python-matplotlib包。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM