python3 用地面雨量計數據校正TRMM/3B43數據之模型建立

本文數據爲處理後的TRMM累計年降水量數據和雨量計累計年降水量數據

# -*- coding: utf-8 -*-
"""
Created on Tue Nov 12 19:31:07 2019

@author: BAI Depei
"""

from osgeo import ogr
from osgeo import gdal
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
from scipy import polyfit,polyval,sqrt,stats

#------------------read the station_coordinates--------------------
fn = 'E:\課程PPT\Python空間數據處理\python空間數據處理-期中大作業02\梅川江地面數據\meichuan_prec_station.shp'
ds = ogr.Open(fn,False)
layer = ds.GetLayer(0)
spatialref = layer.GetSpatialRef()
lydefn = layer.GetLayerDefn()  #圖層定義信息
geomtype = lydefn.GetGeomType()
fieldlist = [] 
for i in range(lydefn.GetFieldCount()):
    fddefn = lydefn.GetFieldDefn(i)
    fddict = {'name':fddefn.GetName(),'type':fddefn.GetType(),\
              'width':fddefn.GetWidth(),'decimal':fddefn.GetPrecision()}
    fieldlist += [fddict]
    #獲取屬性表每列列名及其屬性:類型、寬度、精度
    geomlist,reclist = [],[]
    #geomlist存放所有圖形的座標點(字符串中包含),reclist存放所有的圖形名
    feature = layer.GetNextFeature()
    #首次獲取feature
    while feature is not None:
        geom = feature.GetGeometryRef()
        geomlist += [geom.ExportToWkt()]
        rec = {}
        for fd in fieldlist:
            rec[fd['name']] = feature.GetField(fd['name'])
        reclist += [rec]
        feature = layer.GetNextFeature()
ds.Destroy()
#關閉數據
#-------------------------將座標寫入列表中---------------------------------
pnt_coordinates = [[],[]]
for i in range(len(geomlist)):
    a = geomlist[i].split(' ')
    b = a[1].split('(')
    c = a[2].split(')')
    longitude = float(b[1])
    latitude = float(c[0])
    pnt_coordinates[0] += [longitude]
    pnt_coordinates[1] += [latitude]
#reclist則不必寫入其他變量,因其調用簡單

#-------------------------讀取2010年TRMM降水遙感圖像-----------------------
path = 'E:\\課程PPT\\Python空間數據處理\\python空間數據處理-期中大作業02\\衛星降雨數據TRMM3B43_分辨率0.25度\\'
#有時候路徑必須雙反斜槓
dataset = gdal.Open(path + '3B43_2010.TIF')
samples = dataset.RasterXSize
lines = dataset.RasterYSize
bands = dataset.RasterCount
img_geotrans = dataset.GetGeoTransform()
#Out[10]: (-180.0, 0.25, 0.0, 50.0, 0.0, -0.25)
img_proj = dataset.GetProjection()
#Out[12]: 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"...]]]
#可以看到此遙感圖像未進行投影定義,因此還不是投影座標,只是地理座標
#在求解這些實測站點位於圖像中哪個行列位置時不用將其轉爲投影座標
im_data = dataset.ReadAsArray(0,0,samples,lines)

del dataset
#-----------------------轉換站點經緯度座標到對應遙感圖像上的行列號----------
im_loc = [[],[]]
#第一個列表放行號,存緯度換出來的值,後者爲列號,存經度換出來的值
# variable += [value] 等同於 variable.append(value)
for i in range(len(pnt_coordinates[0])):
    sample = sp.Symbol('sample')
    line = sp.Symbol('line')
    #pnt_coordinates[0][i] = img_geotrans[0] + sample*img_geotrans[1] + line*img_geotrans[2]
    #pnt_coordinates[1][i] = img_geotrans[3] + sample*img_geotrans[4] + line*img_geotrans[5]
    a = -pnt_coordinates[0][i] + img_geotrans[0] + sample*img_geotrans[1] + line*img_geotrans[2]
    b = -pnt_coordinates[1][i] + img_geotrans[3] + sample*img_geotrans[4] + line*img_geotrans[5]
    answer = sp.solve([a,b],[sample,line])#解二元一次方程組
    #Out[15]: {x: 0, y: 1}
    line = int(np.floor(answer[line]))
    sample = int(np.floor(answer[sample]))
    im_loc[0] += [line]
    im_loc[1] += [sample]
#----------------------read 2010_TRMM_stationpnt_value-------------------------    
data_TRMM_stationpnt = []
for i in range(len(im_loc[0])):
    data_TRMM_stationpnt += [im_data[im_loc[0][i],im_loc[1][i]]]
#----------------------read 2010_rain_gauge_value------------------------------
path2 = 'E:\\課程PPT\\Python空間數據處理\\python空間數據處理-期中大作業02\\梅川江地面數據\\'
file_handle = open(path2 + 'meichuan_precipitation_2007-2010.txt')
line_value = file_handle.readlines()
file_handle.close()

#data_TRMM_stationpnt是根據geomlist次序依次遍歷獲得的,
#而geomlist次序與reclist次序一致,因此用reclist中臺站名和2010作爲關鍵字去檢索
data_rain_gauge = []
#站點數據
for i in range(1,len(line_value)):
    temp = line_value[i][:-2].split(',')
    #Out[3]: '200704,DongShao,184.200000\n'
    if temp[0] != '201001':
        i += 12
        continue
    else:
        data = []
        for j in range(12):
            temp  = line_value[i+j][:-2].split(',')
            data += [float(temp[2])]
    total_value = sum(data)
    data_rain_gauge +=  [total_value]
    i += 12
    continue
#---------------built model between TRMM and rain_gauge_pnt----------------
#use 2010's data to built the linear model
#data_TRMM_stationpnt: X
#data_rain_gauge: Y
#Y = ax + b
(a,b) = np.polyfit(data_TRMM_stationpnt,data_rain_gauge,1)
mean_TRMM = np.mean(data_TRMM_stationpnt)
mean_gauge = np.mean(data_rain_gauge)
TRMM1 = data_TRMM_stationpnt - mean_TRMM
gauge1 = data_rain_gauge - mean_gauge
gauge2 = sum((data_TRMM_stationpnt - mean_TRMM)**2)
TRMM_gauge = sum(TRMM1 * gauge1)
#迴歸參數的最小二乘估計
#beta1=xy/x2
#beta0=y_m-beta1*x_m
#輸出線性迴歸方程
print('y=',b,'+',a,'* x')
#方差的無偏估計量
sigma2=sum((np.array(data_rain_gauge) - b - a*np.array(data_TRMM_stationpnt))**2)/61
#自由度爲63-2=61,見概率論與數理統計(浙江大學版) P.250-251.
sigma=np.sqrt(sigma2) #標準差
t=a*np.sqrt(gauge2)/sigma #t值
print('t=',t) #已知臨界值求p值
p=stats.t.sf(t,61)
#見概率論與數理統計P.214
print('p=',p)
R2 = a*a
square = (np.array(data_TRMM_stationpnt)-np.array(data_rain_gauge))**2
RMSE = np.sqrt(np.array(sum(square)/63))
regression_x = np.linspace(1200,2600,200)
regression_y = [b + a*i for i in regression_x] 
#plt.axis([1200,2600,1200,2600])
#plt.axis('equal')
#-------------------------設置圖形的長寬------------------------
fig = plt.gcf()
fig.set_size_inches(10,8)
#------------------------橫縱座標範圍---------------------------
plt.xlim(xmax = 2600, xmin=1200)
plt.ylim(ymax = 2600, ymin=1200)
#-----------------------刻度值大小及字體------------------------
plt.tick_params(labelsize=20)
#[label.set_fontname('Times New Roman') for label in labels]
#-------------------------畫擬合直線和散點及圖例----------------------
plt.scatter(np.array(data_TRMM_stationpnt),np.array(data_rain_gauge),c = 'g',\
            marker = '8')
plt.plot(np.array(regression_x),np.array(regression_y),'r',linewidth = 3)
#label = 'y='+str(round(a,3))+'*x+'+str(round(b,3)),\
#-------------------------圖名和橫縱座標名稱及格式----------------
plt.xlabel('TRMM value',{'size':24,'family' : 'Times New Roman'})
plt.ylabel('rain gauge value',{'size':24,'family' : 'Times New Roman'})
#plt.text('N = 63')
#,'R2 = '+str(R2)
#,['p_value = '+str(p),'RMSE = '+str(RMSE)]
plt.legend(loc = 'upper left',frameon = False)
plt.savefig('linear_model.png',dpi=300,bbox_inches='tight')
#bbox_inches = 'tight'用來去除圖形邊界
plt.show()       

在這裏插入圖片描述
做進一步美化,得到:
在這裏插入圖片描述
關於如何在散點圖上添加公式,使圖片和公式合併,且不影響圖像的分辨率,過程參考:
[1]小白是哪個小白_. 怎麼把公式和圖片合併起來?


版權歸作者 小白是哪個小白_ 所有,轉載、引用請註明鏈接出處。

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