作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝!
在資料視覺效果過程中,我們常常需要將資料根據其採集的地理位置在地圖上顯示出來。比如說我們會想要在地圖上畫出城市,飛機的航線,乃至于軍事基地等等。通常來說,一個地理資訊系統都會帶有這樣的功能。今天我們討論如何在Python上實現,並且使用免費的工具包。
matplotlib是python上常用的一個資料繪製包。它基於numpy(numpy是python用於數組運算的一個包)。matplotlib具有強大的資料繪製功能,可以輕易地畫出各種統計圖形,比如散佈圖,條行圖,餅圖等等。而Matplot中的basemap則允許我們繪製出地圖,並在地圖上繼續畫出資料。
( matplotlib經常與numpy和scipy相配合,用於科學研究。他們是Matlab的強勁對手,這相當可以理解,因為Matlab一套需要好幾千塊,而python工具則是免費的。)
我們今天的目標是用上述工具畫出亞洲主要城市的人口。如所示,人口的多少以橙色小圓圈的大小表示:
資料如下(我從Wikipedia上整理的,你可以隨意使用),我將資料儲存在檔案major_city:
Shanghai 23019148 31.23N 121.47E ChinaMumbai 12478447 18.96N 72.82E IndiaKarachi 13050000 24.86N 67.01E PakistanDelhi 16314838 28.67N 77.21E IndiaManila 11855975 14.62N 120.97E PhilippinesSeoul 23616000 37.56N 126.99E Korea(South)Jakarta 28019545 6.18S 106.83E IndonesiaTokyo 35682460 35.67N 139.77E JapanPeking 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 Basemapimport matplotlib.pyplot as pltimport numpy as np#============================================# read datanames = []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 colormap.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 parameterssize_factor = 80.0y_offset = 15.0rotation = 30for 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繪圖。
map = Basemap(projection='ortho',lat_0=35,lon_0=120,resolution='l')
設定了地圖投影的方法。從球形的地球表面投影到平面地圖有許多方法可以選擇,得到的結果也非常不同。
我們的經緯度通過
x, y = map(lons, lats)
語句轉換為映像上的位置,並通過
cs = map.scatter(i,j,s=size,marker='o',color='#FF5600')
畫散佈圖的方法在地圖上畫出來。
文中的需要的軟體包包括:
numpy, matplotlib, mpl_toolkits
你可以google並找到相關文檔。
你可以使用pip來下載安裝各個包。
在Ubuntu的repository中,你可以找到python-matplotlib包。
參考 Python小技巧
另外,如果是也可以下載epd python。它整合了python以及所有的軟體包。(epd python是商業版,但對於學術使用者免費。)