python對站點(diǎn)數(shù)據(jù)做EOF且做插值繪制填色圖
前言
讀取站點(diǎn)資料數(shù)據(jù)對站點(diǎn)數(shù)據(jù)進(jìn)行插值,插值到規(guī)則網(wǎng)格上繪制EOF第一模態(tài)和第二模態(tài)的空間分布圖繪制PC序列
關(guān)于插值,這里主要提供了兩個插值函數(shù),一個是一般常用的規(guī)則網(wǎng)格插值:
griddata
另一個是metpy中的:
inverse_distance_to_grid()
本來只是測驗一下不同插值方法,但是發(fā)現(xiàn)兩種插值方法的結(jié)果差別很大,由于對于站點(diǎn)數(shù)據(jù)處理較少,所以不太清楚具體原因。如果有知道的朋友可以告知一下,不甚感謝!
本次數(shù)據(jù)存儲的文件格式為.txt
,讀取的方法是通過pandas.read_csv()
同時,之前一直嘗試使用proplot進(jìn)行繪圖,較長時間不用matplotlib.pyplot繪圖了,也當(dāng)做是復(fù)習(xí)一下繪圖過程。
繪圖中的代碼主要通過封裝函數(shù),這樣做的好處是大大減少了代碼量。
導(dǎo)入必要的庫:
from eofs.standard import Eof import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import griddata import pandas as pd import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.feature as cfeature from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter from metpy.interpolate import inverse_distance_to_grid
出現(xiàn)找不到庫的報錯,這里使用conda install packagename
安裝一下就好
讀取存儲的數(shù)據(jù)
##################### read station data ########################################## path = r'D:/data.txt' file = pd.read_csv(path,sep= "\t", header=None, names=['station','lat','lon','year','data'], na_values=-99.90) data = file['data'].to_numpy() lon = file['lon'].to_numpy() lat = file['lat'].to_numpy() year = file['year'].to_numpy() station = file['station'].to_numpy() year_max = np.max(year) year_min = np.min(year) year_range = np.arange(year_min,year_max+1,1) data_all = data.reshape(70,53) lon_all = lon.reshape(70,53)/100 lat_all = lat.reshape(70,53)/100 lon_real = lon_all[:,0] lat_real = lat_all[:,0]
這里將讀取的數(shù)據(jù)全部轉(zhuǎn)為array
格式,方便查看以及后續(xù)處理。本來存儲的文件中是沒有相關(guān)的經(jīng)度、緯度、站點(diǎn)、時間的名稱的,這里我是自己加在上面方面數(shù)據(jù)讀取的。
本次處理的數(shù)據(jù)包含70個站點(diǎn),53年
插值
##################### interp data ########################################## ### interp data to target grid ### set target grid lon_target = np.arange(115,135.5,0.5) lat_target = np.arange(38,55.5,0.5) x_t, y_t = np.meshgrid(lon_target, lat_target) z = np.zeros((len(year_range),lat_target.shape[0],lon_target.shape[0])) for i in range(len(year_range)): print(i) # z[i] = inverse_distance_to_grid(lon_real,lat_real, # data_all[:,i], # x_t,y_t, r=15, min_neighbors=3) z[i] = griddata((lon_real,lat_real), data_all[:,i], (x_t,y_t),method='cubic')
這里顯示了使用griddata()
的插值過程,metpy的過程注釋掉了,需要測試的同學(xué)之間取消注釋即可。
注意點(diǎn):插值過程需要先設(shè)置目標(biāo)的插值網(wǎng)格。
EOF處理
#計算緯度權(quán)重 lat_new = np.array(lat_target) coslat=np.cos(np.deg2rad(lat_new)) wgts = np.sqrt(coslat)[..., np.newaxis] #創(chuàng)建EOF分解器 solver=Eof(z,weights=wgts) eof=solver.eofsAsCorrelation(neofs=2) #此處的neofs的值是我們需要的空間模態(tài)數(shù) pc=solver.pcs(npcs=2,pcscaling=1)#方差 var=solver.varianceFraction(neigs=2)
這里沒啥好說的,需要幾個模態(tài)自由選擇即可
定義繪圖函數(shù)并繪圖
##################### def plot function ########################################## def contourf(ax,i,level,cmap): extents = [115,135,35,55] ax.set_extent(extents, crs=proj) ax.add_feature(cfeature.LAND, edgecolor='black',facecolor='silver', ) ax.add_feature(cfeature.LAKES, edgecolor='black',facecolor='w', ) ax.add_feature(cfeature.BORDERS) xtick = np.arange(extents[0], extents[1], 5) ytick = np.arange(extents[2], extents[3], 5) ax.coastlines() tick_proj = ccrs.PlateCarree() c = ax.contourf(lon_target,lat_target,eof[i], transform=ccrs.PlateCarree(), levels=level, extend='both', cmap=cmap) ax.set_xticks(xtick, crs=tick_proj) ax.set_xticks(xtick, crs=tick_proj) ax.set_yticks(ytick, crs=tick_proj) ax.set_yticks(ytick, crs=tick_proj) ax.xaxis.set_major_formatter(LongitudeFormatter()) ax.yaxis.set_major_formatter(LatitudeFormatter()) plt.yticks(fontproperties='Times New Roman',size=10) plt.xticks(fontproperties='Times New Roman',size=10) ax.tick_params(which='major', direction='out', length=4, width=0.5, pad=5, bottom=True, left=True, right=True, top=True) ax.tick_params(which='minor', direction='out', bottom=True, left=True, right=True, top=True) ax.set_title( 'EOF'+str(i),loc='left',fontsize =15) return c def p_line(ax,i): ax.set_title('pc'+str(i)+'',loc='left',fontsize = 15) # ax.set_ylim(-3.5,3.5) ax.axhline(0,linestyle="--") ax.plot(year_range,pc[:,i],color='blue') ax.set_ylim(-3,3) ##################### plot ########################################## fig = plt.figure(figsize=(8, 6), dpi=200) proj = ccrs.PlateCarree() contourf_1 = fig.add_axes([0.02,0.63,0.5,0.3],projection=proj) c1=contourf(contourf_1,0,np.arange(0.7,1,0.05),plt.cm.bwr) plot_1 = fig.add_axes([0.45,0.63,0.5,0.3]) p_line(plot_1,0) contourf_2 = fig.add_axes([0.02,0.15,0.5,0.3],projection=proj) c2= contourf(contourf_2,1,np.arange(-0.5,0.6,0.1),plt.cm.bwr) plot_2 = fig.add_axes([0.45,0.15,0.5,0.3],) p_line(plot_2,1) cbposition1 = fig.add_axes([0.16, 0.55, 0.22, 0.02]) cb = fig.colorbar(c1,cax=cbposition1, orientation='horizontal',format='%.1f') cb.ax.tick_params(which='both',direction='in') cbposition2=fig.add_axes([0.16, 0.08, 0.22, 0.02]) cb2 = fig.colorbar(c2,cax=cbposition2, orientation='horizontal',format='%.1f') cb2.ax.tick_params(which='both',direction='in') plt.show()
這里將大部分重復(fù)的繪圖代碼,進(jìn)行了封裝,通過封裝好的函數(shù)進(jìn)行調(diào)用,大大簡潔了代碼量。相關(guān)的封裝過程之前也有講過,可以翻看之前的記錄。
展示結(jié)果
使用griddata
的繪圖結(jié)果:
使用metpt插值函數(shù)
的結(jié)果:
附上全部的繪圖代碼:
# -*- coding: utf-8 -*- """ Created on Fri Sep 23 17:46:42 2022 @author: Administrator """ from eofs.standard import Eof import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import griddata import pandas as pd import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.feature as cfeature from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter from metpy.interpolate import inverse_distance_to_grid ##################### read station data ########################################## path = r'D:/data.txt' file = pd.read_csv(path,sep= "\t", header=None, names=['station','lat','lon','year','data'], na_values=-99.90) data = file['data'].to_numpy() lon = file['lon'].to_numpy() lat = file['lat'].to_numpy() year = file['year'].to_numpy() station = file['station'].to_numpy() year_max = np.max(year) year_min = np.min(year) year_range = np.arange(year_min,year_max+1,1) data_all = data.reshape(70,53) lon_all = lon.reshape(70,53)/100 lat_all = lat.reshape(70,53)/100 lon_real = lon_all[:,0] lat_real = lat_all[:,0] ##################### interp data ########################################## ### interp data to target grid ### set target grid lon_target = np.arange(115,135.5,0.5) lat_target = np.arange(38,55.5,0.5) x_t, y_t = np.meshgrid(lon_target, lat_target) z = np.zeros((len(year_range),lat_target.shape[0],lon_target.shape[0])) for i in range(len(year_range)): print(i) # z[i] = inverse_distance_to_grid(lon_real,lat_real, # data_all[:,i], # x_t,y_t, r=15, min_neighbors=3) z[i] = griddata((lon_real,lat_real), data_all[:,i], (x_t,y_t),method='cubic') #計算緯度權(quán)重 lat_new = np.array(lat_target) coslat=np.cos(np.deg2rad(lat_new)) wgts = np.sqrt(coslat)[..., np.newaxis] #創(chuàng)建EOF分解器 solver=Eof(z,weights=wgts) eof=solver.eofsAsCorrelation(neofs=2) #此處的neofs的值是我們需要的空間模態(tài)數(shù) pc=solver.pcs(npcs=2,pcscaling=1)#方差 var=solver.varianceFraction(neigs=2) ##################### def plot function ########################################## def contourf(ax,i,level,cmap): extents = [115,135,35,55] ax.set_extent(extents, crs=proj) ax.add_feature(cfeature.LAND, edgecolor='black',facecolor='silver', ) ax.add_feature(cfeature.LAKES, edgecolor='black',facecolor='w', ) ax.add_feature(cfeature.BORDERS) xtick = np.arange(extents[0], extents[1], 5) ytick = np.arange(extents[2], extents[3], 5) ax.coastlines() tick_proj = ccrs.PlateCarree() c = ax.contourf(lon_target,lat_target,eof[i], transform=ccrs.PlateCarree(), levels=level, extend='both', cmap=cmap) ax.set_xticks(xtick, crs=tick_proj) ax.set_xticks(xtick, crs=tick_proj) ax.set_yticks(ytick, crs=tick_proj) ax.set_yticks(ytick, crs=tick_proj) ax.xaxis.set_major_formatter(LongitudeFormatter()) ax.yaxis.set_major_formatter(LatitudeFormatter()) plt.yticks(fontproperties='Times New Roman',size=10) plt.xticks(fontproperties='Times New Roman',size=10) ax.tick_params(which='major', direction='out', length=4, width=0.5, pad=5, bottom=True, left=True, right=True, top=True) ax.tick_params(which='minor', direction='out', bottom=True, left=True, right=True, top=True) ax.set_title( 'EOF'+str(i),loc='left',fontsize =15) return c def p_line(ax,i): ax.set_title('pc'+str(i)+'',loc='left',fontsize = 15) # ax.set_ylim(-3.5,3.5) ax.axhline(0,linestyle="--") ax.plot(year_range,pc[:,i],color='blue') ax.set_ylim(-3,3) ##################### plot ########################################## fig = plt.figure(figsize=(8, 6), dpi=200) proj = ccrs.PlateCarree() contourf_1 = fig.add_axes([0.02,0.63,0.5,0.3],projection=proj) c1=contourf(contourf_1,0,np.arange(0.7,1,0.05),plt.cm.bwr) plot_1 = fig.add_axes([0.45,0.63,0.5,0.3]) p_line(plot_1,0) contourf_2 = fig.add_axes([0.02,0.15,0.5,0.3],projection=proj) c2= contourf(contourf_2,1,np.arange(-0.5,0.6,0.1),plt.cm.bwr) plot_2 = fig.add_axes([0.45,0.15,0.5,0.3],) p_line(plot_2,1) cbposition1 = fig.add_axes([0.16, 0.55, 0.22, 0.02]) cb = fig.colorbar(c1,cax=cbposition1, orientation='horizontal',format='%.1f') cb.ax.tick_params(which='both',direction='in') cbposition2=fig.add_axes([0.16, 0.08, 0.22, 0.02]) cb2 = fig.colorbar(c2,cax=cbposition2, orientation='horizontal',format='%.1f') cb2.ax.tick_params(which='both',direction='in') plt.show()
總結(jié)
metpy的插值函數(shù)
好處在于可以自由填充整個繪圖區(qū)域,但是感覺griddata
函數(shù)的插值結(jié)果更加符合預(yù)期,雖然也有點(diǎn)怪怪的。
到此這篇關(guān)于python對站點(diǎn)數(shù)據(jù)做EOF且做插值繪制填色圖的文章就介紹到這了,更多相關(guān)python EOF插值繪制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python處理字節(jié)串:struct.pack和struct.unpack使用
這篇文章主要介紹了Python處理字節(jié)串:struct.pack和struct.unpack使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01詳解利用django中間件django.middleware.csrf.CsrfViewMiddleware防止csrf
這篇文章主要介紹了詳解利用django中間件django.middleware.csrf.CsrfViewMiddleware防止csrf攻擊,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10python?泛型函數(shù)--singledispatch的使用解讀
這篇文章主要介紹了python?泛型函數(shù)--singledispatch的使用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09在VS Code上搭建Python開發(fā)環(huán)境的方法
這篇文章主要介紹了在VS Code上搭建Python開發(fā)環(huán)境的方法,需要的朋友可以參考下2018-04-04利用一個簡單的例子窺探CPython內(nèi)核的運(yùn)行機(jī)制
這篇文章主要介紹了利用一個簡單的例子窺探CPython內(nèi)核的運(yùn)行機(jī)制,作者通過一個簡單的輸出函數(shù)深入、介紹了CPython源碼C代碼中的一些函數(shù),需要的朋友可以參考下2015-03-03