Python遙感可視化 — Basemap將地面觀測站點進行空間插值可視化

歡迎關注博主的微信公衆號:“智能遙感”。

該公衆號將爲您奉上Python地學分析、爬蟲、數據分析、Web開發、機器學習、深度學習等熱門源代碼。

本人的GitHub代碼資料主頁(持續更新中,多給Star,多Fork):

https://github.com/xbr2017

CSDN也在同步更新:

https://blog.csdn.net/XBR_2014


“本節主要內容是將地面觀測站點數據在地圖上顯示,並且對站點數據進行空間插值,從而可以將點數據轉化爲柵格數據,柵格數據具有較好的空間連續性。”

今天的遙感之美封面圖—白雪下的麥肯齊河系統。乍一看,有一種山迴路轉不見君,雪上空留馬行處的景象。麥肯齊河系統是加拿大最大的流域,也是世界上第十大流域。這條河從加拿大落基山脈的哥倫比亞冰原到達北冰洋,全長4,200公里。

2016年11月7日由Landsat 8上OLI傳感器拍攝的圖像,該圖顯示了Mackenzie River Delta的一部分 - 包括沿着河道東部的這條冰凍高速公路。由白色冰雪覆蓋的水道在綠色松樹覆蓋的土地上脫穎而出。


PM2.5可視化

在平時遙感數據可視化時,等經緯度投影是我們最長使用的一種方法,也是最簡單的投影。等經緯度投影又稱等距圓柱投影,是假想球面與圓筒面相切於赤道,赤道爲沒有變形的線。經緯線網格,同一般正軸圓柱投影,經緯線投影成兩組相互垂直的平行直線。其特性是:保持經距和緯距相等,經緯線成正方形網格;沿經線方向無長度變形;角度和麪積等變形線與緯線平行,變形值由赤道向高緯逐漸增大。該投影適合於低緯地區製圖。

首先來看一下Basemap官網上的參考代碼,這是最簡單的顯示全球地圖的方式(圖1):大陸廓線(未添加國家行政邊界)以及陸地(橘黃色)、海洋(淺綠色)、內陸湖泊(藍色)的顏色填充,讓人更加直觀地瞭解各大洲的分佈情況。

代碼實現:

# _*_ coding: utf-8 _*_
__author__ = 'xbr'
__date__ = '2019/1/11 14:09'

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

maps = Basemap(projection='cyl', lat_0=0, lon_0=0)
# 首先給地球塗上藍色
maps.drawmapboundary(fill_color='aqua')
# 再給大陸塗上橘黃色,給江河湖泊塗上大海一樣的顏色
maps.fillcontinents(color='coral', lake_color='blue')
maps.drawcoastlines()
plt.show()
# plt.savefig('test.png')

結果圖:

圖1 等經緯度投影下的世界地圖

在上述基礎之上,我們將地面觀測站點數據疊加到底圖上,來分析數據的時空變化。下面以2018年01月01日中國地區PM2.5觀測數據爲例,圖2展示全國PM2.5站點空間分佈,我們發現中國東部地區觀測站點數量加多,並且點相對較大,點的大小對應PM2.5數值的高低,說明東部地區這一天的大氣污染較西部地區較爲嚴重。

圖2 全國PM2.5站點分佈,點越大說明PM2.5濃度越高

但是上圖不能夠很好地反應PM2.5的空間變化,從視覺效果來看,顏色較爲單一。因此,我們給每個站點添加顏色,顏色越紅,表示PM2.5濃度越大,也就是空氣質量越差(見下圖)。點的顏色和大小可以同時表示數值大小,更加增強了數據的可視化效果。

圖3 全國PM2.5站點分佈,顏色越紅且點越大說明PM2.5濃度越高

代碼實現:

# _*_ coding: utf-8 _*_
__author__ = 'xbr'
__date__ = '2019/1/11 14:49'

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 用來正常顯示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
# 用來正常顯示負號
plt.rcParams['axes.unicode_minus'] = False
# 獲取PM2.5數據
df = pd.read_excel(r'D:\data\20180101PM25-CHINA.xlsx')
# 剔除無效值NAN
df = df.dropna(axis=0, how='any')

lat = np.array(df["lat"][:])  # 獲取維度之維度值
lon = np.array(df["lon"][:])  # 獲取經度值
PM25 = np.array(df["PM25"][:], dtype=float)
# 畫圖
fig = plt.figure(figsize=(16, 9))
plt.rc('font', size=15, weight='bold')
ax = fig.add_subplot(111)
# 添加標題,PM2.5下標設置
plt.title(u'2018年01月01日中國地區$\mathrm{PM}_{2.5}$質量濃度分佈', size=25, weight='bold')
# 創建底圖,等經緯度投影
mp = Basemap(llcrnrlon=73., llcrnrlat=17.,
             urcrnrlon=135., urcrnrlat=55,
             projection='cyl', resolution='h')
# 添加海岸線
mp.drawcoastlines()
# 添加國家行政邊界
mp.drawcountries()
# 設置colorbar中顏色間隔個數
levels = np.linspace(0, np.max(PM25), 20)
# cf = mp.scatter(lon, lat, PM25, marker='o', color='r')
# 設置顏色表示數值大小
cf = mp.scatter(lon, lat, PM25, c=PM25, cmap='jet', alpha=0.75)
# 設置上下標以及單位的希臘字母
cbar = mp.colorbar(cf, location='right', format='%d', size=0.3,
                   ticks=np.linspace(0, np.max(PM25), 10),
                   label='$\mathrm{PM}_{2.5}$($\mu$g/$\mathrm{m}^{3}$)')
plt.show()

地面站點數據觀測精度相對較高,但是不能夠覆蓋所有的空間範圍。爲了研究大範圍連續空間的特徵變化,通常需要對站點數據進行空間插值,例如克里金插值、樣條插值、反距離加權。下面以三種插值爲例(最鄰近插值、線性插值和三次樣條插值)。如果喜歡克里金插值的小夥伴,可以pykrige模塊去實現,本節不作講解。

圖4 最鄰近插值後,全國PM2.5空間分佈,顏色越紅說明PM2.5濃度越高

圖5 線性插值後,全國PM2.5空間分佈,顏色越紅說明PM2.5濃度越高

圖6 三次樣條插值後,全國PM2.5空間分佈,顏色越紅說明PM2.5濃度越高

說明:三次樣條插值後的效果其實分佈也是連續的,與圖5很相似,但是在Basemap上顯示就出現破碎現象,目前還不知道什麼原因。

代碼實現:

# _*_ coding: utf-8 _*_
__author__ = 'xbr'
__date__ = '2019/1/11 14:49'

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy.interpolate import griddata
import cmaps

# 用來正常顯示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
# 用來正常顯示負號
plt.rcParams['axes.unicode_minus'] = False
# 獲取PM2.5數據
df = pd.read_excel(r'D:\data\20180101PM25-CHINA.xlsx')
# 剔除無效值NAN
df = df.dropna(axis=0, how='any')
# 獲取緯度
lat = np.array(df["lat"][:])
# 獲取經度
lon = np.array(df["lon"][:])
# 獲取PM2.5
PM25 = np.array(df["PM25"][:])
# 創建格網
grid_x, grid_y = np.mgrid[73.56:135.04, 18.2:53.56]
# 插值方法:'nearest', 'linear', 'cubic'
grid_z = griddata((lon, lat), PM25, (grid_x, grid_y), method='cubic')

# 畫圖
fig = plt.figure(figsize=(16, 9))
plt.rc('font', size=15, weight='bold')
ax = fig.add_subplot(111)
# 添加標題,PM2.5下標設置
plt.title(u'2018年01月01日中國地區$\mathrm{PM}_{2.5}$質量濃度分佈', size=25, weight='bold')
# 創建底圖,等經緯度投影
mp = Basemap(llcrnrlon=73., llcrnrlat=17.,
             urcrnrlon=135., urcrnrlat=55,
             projection='cyl', resolution='h')
# 添加海岸線
mp.drawcoastlines()
# 添加國家行政邊界
mp.drawcountries()
# 設置colorbar中顏色間隔個數
levels = np.linspace(0, np.max(PM25), 20)
cf = mp.contourf(grid_x, grid_y, grid_z, levels=levels, cmap=cmaps.GMT_panoply)
cbar = mp.colorbar(cf, location='right', format='%d', size=0.3,
                   ticks=np.linspace(0, np.max(PM25), 10),
                   label='$\mathrm{PM}_{2.5}$($\mu$g/$\mathrm{m}^{3}$)')
plt.show()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章