简体   繁体   English

使用Python将3D笛卡尔坐标转换为Polar NetCDF数据

[英]Regrid 3D Cartesian to Polar NetCDF Data with Python

I have a NetCDF variable with the dimensions of time, x, y. 我有一个NetCDF变量,其时间为x,y。 It is currently in cartesian coordinates but I need the data in polar coordinates. 当前是笛卡尔坐标,但我需要极坐标的数据。 I have tried creating a function to do this, but I cannot seem to get it right. 我尝试创建一个函数来执行此操作,但似乎无法正确执行。 Does anyone know if there is a simpler way to do this? 有谁知道是否有更简单的方法来做到这一点?

def regrid(x,y,xcent,ycent,vardat):
    x=np.subtract(x,xcent)
    y=np.subtract(y,ycent)
    threshmin = np.min(vardat)
    threshmax = np.max(vardat)
    rmax = np.ceil(np.sqrt(((x[-1]-x[0])/2.)**2 + ((y[-1]-y[0])/2.)**2))
    r = np.arange(0,rmax,(x[1]-x[0]))
    theta_inc = np.floor(np.arctan2(y[1]-y[0],(x[-1]-x[0])/2.)/np.pi*180.)
    if theta_inc <1.0:
        theta_inc = 1
    theta = np.arange(0,(360-theta_inc),theta_inc)
    r2d, theta2d = np.meshgrid(r,theta)
    x_polar = r2d*np.cos(np.pi/180.*theta2d)
    y_polar = r2d*np.sin(np.pi/180.*theta2d)
    x_range = np.arange(x[0],x[-1]+1,(x[1]-x[0]))
    y_range = np.arange(y[0],y[-1]+1,(y[1]-y[0]))
    field_rt = np.zeros((len(r),len(theta)))


    field_interp = interp2d(x_range,y_range,vardat,kind='linear')
    for i in np.arange(0,len(r)):
        for j in np.arange(0,len(theta)):

    *       field_rt[i,j] = field_interp(x_polar[i,j],y_polar[i,j])

    return r, theta, field_rt

r1,theta1, field = regrid(we_ea,no_so,124,124,olr[0,:,:])

At the moment, I get an error saying "index 176 is out of bounds for axis 1 with size 176" at the line with the *. 此刻,我收到一个错误,说在带有*的行上“索引176超出了轴1的大小176”。

Any help is appreciated. 任何帮助表示赞赏。

Here is a (not optimized) nearest neighbour approach to remap data from a regular cartesian grid to a regular polar grid. 这是一种(未优化的)最近邻方法,用于将数据从规则的笛卡尔网格重新映射到规则的极坐标网格。 The coordinate spacings dr and dphi should be adjusted to your needs. 坐标间距drdphi应该根据需要进行调整。 You might also search for the N nearest neighbours and apply some statistical measure, eg a distance weighted average or so. 您也可以搜索N个最近的邻居并应用一些统计量度,例如距离加权平均值。 For large datasets I would recommend using pykdtree to speed up the nearest neighbour search. 对于大型数据集,我建议使用pykdtree来加快最近的邻居搜索的速度。 For remapping geospatial data there is a nice and fast package called pyresample . 为了重新映射地理空间数据,有一个很好的快速包叫做pyresample

import numpy as np
import matplotlib.pyplot as plt

deg2rad = np.pi/180.0

# Define properties of cartesian grid
x_vals = np.arange(-1, 1, 0.01)
y_vals = np.arange(-1, 1, 0.01)
mx, my = np.meshgrid(y_vals, x_vals)

# Define data on cartesian grid
data_cart = np.sin(mx) + np.cos(my)

# Define properties of polar grid
dr = 0.1
dphi = 1*deg2rad
rmax = np.sqrt(x_vals.max()**2 + y_vals.max()**2)
r_vals = np.arange(0, rmax, dr)
phi_vals = np.arange(0, 2*np.pi, dphi)
if len(r_vals)*len(phi_vals) > len(x_vals)*len(y_vals):
    print "Warning: Oversampling"
mr, mphi = np.meshgrid(phi_vals, r_vals)

# Initialize data on polar grid with fill values
fill_value = -9999.0
data_polar = fill_value*np.ones((len(r_vals), len(phi_vals)))

# Define radius of influence. A nearest neighbour outside this radius will not
# be taken into account.
radius_of_influence = np.sqrt(0.1**2 + 0.1**2)

# For each cell in the polar grid, find the nearest neighbour in the cartesian
# grid. If it lies within the radius of influence, transfer the corresponding
# data.
for r, row_polar in zip(r_vals, range(len(r_vals))):
    for phi, col_polar in zip(phi_vals, range(len(phi_vals))):
        # Transform polar to cartesian
        x = r*np.cos(phi)
        y = r*np.sin(phi)

        # Find nearest neighbour in cartesian grid
        d = np.sqrt((x-mx)**2 + (y-my)**2)
        nn_row_cart, nn_col_cart = np.unravel_index(np.argmin(d), d.shape)
        dmin = d[nn_row_cart, nn_col_cart]

        # Transfer data
        if dmin <= radius_of_influence:
            data_polar[row_polar, col_polar] = data_cart[nn_row_cart, nn_col_cart]

# Mask remaining fill values
data_polar = np.ma.masked_equal(data_polar, fill_value)

# Plot results
plt.figure()
im = plt.pcolormesh(mx, my, data_cart)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Cartesian')
plt.colorbar(im)

plt.figure()
ax = plt.subplot(111, projection='polar')
im = ax.pcolormesh(mr, mphi, data_polar)
ax.set_title('Polar')
plt.colorbar(im)

plt.show()

在此处输入图片说明 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM