绘制MetPy Q向量

时间:2019-04-04 14:14:09

标签: metpy

我无法从GFS数据中的metpy.calc绘制Q矢量;应用ax.set_extentax.quiver

时,矢量无法正确绘制

计算代码:

import metpy.calc as mpcalc

query.variables('Temperature_isobaric', 'Geopotential_height_isobaric',
                'u-component_of_wind_isobaric', 'v-component_of_wind_isobaric')

data = subset_access.get_data(query)

lat = data.variables['lat'][:]
lon = data.variables['lon'][:]

press = data.variables['isobaric'][:] * units.Pa

# Make the pressure same dimensions as the temperature and winds
pressure_for_calc = press[:, None, None]

temperature = data.variables['Temperature_isobaric'][0] * units.kelvin

u = data.variables['u-component_of_wind_isobaric'][0] * units.meter / 
    units.second

v = data.variables['v-component_of_wind_isobaric'][0] * units.meter / 
    units.second

dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat)

现在我正在尝试通过q-vector函数运行dx和dy:

Q = mpcalc.q_vector(u,v,temperature,pressure_for_calc,dx,dy)

但是我遇到一个错误,我认为这与dx和dy尺寸有关:

IndexError: too many indices for array

dx.shape, dy.shape
>>> ((101, 160), (100, 161))

好的,所以这显然是一个问题;我每个都需要一个一维数组,所以我探查了温度数组的形状:

print(temperature.shape)
>>> (31, 101, 161)

所以我尝试了dx和dy的一个子集:

print(dx[:,0].shape, dy[0,:].shape)
>>> (101,) (161,)

然后我认为这应该与temp和press数组对齐,然后我根据这些子集再次尝试了计算:

Q = mpcalc.q_vector(u,v,temperature,pressure_for_calc,dx[0,:],dy[:,0])

没有错误,现在感觉很好。检查我假设是x和y分量的Q的尺寸:

 print(Q[0].shape, Q[1].shape)
 >>> (31, 101, 161)
 >>> (31, 101, 161)

似乎要排队...

但是,当我查看lats和lons的尺寸时:

lat.shape, lon.shape
>>> ((101,), (161,))

似乎从dx和dy的形状倒退了吗?

我丢失了某些东西还是只是完全错误地计算了Q向量?这是我的第一次尝试,但我不确定我所做的事情一开始是否正确。

真正的问题出在我尝试用ax.quiver

用任何投影对其进行绘制时

绘图代码:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

# Set Projection of Data
datacrs = ccrs.PlateCarree()

# Set Projection of Plot
plotcrs = ccrs.LambertConformal()

# Add Map Features
states_provinces = cfeature.NaturalEarthFeature(category='cultural',
    name='admin_1_states_provinces_lakes',scale='50m', facecolor='none')

country_borders = cfeature.NaturalEarthFeature(category='cultural',
    name='admin_0_countries',scale='50m', facecolor='none')

# Lat/Lon Extents [lon0,lon1,lat0,lat1]
extent = [-130., -70, 20., 60.]
# Create a plot
fig = plt.figure(figsize=(17., 11.))

# Add the map
ax = plt.subplot(111, projection=plotcrs)

# Add state boundaries to plot
ax.add_feature(states_provinces, edgecolor='k', linewidth=1)

# Add country borders to plot
ax.add_feature(country_borders, edgecolor='black', linewidth=1)
lon_slice = slice(None, None, 8)
lat_slice = slice(None, None, 8)

ax.quiver(lon[lon_slice],lat[lat_slice],Q[0][0,lon_slice,lat_slice], Q[1][0,lon_slice,lat_slice],
color='k',transform=plotcrs)

ax.set_extent(extent, datacrs)

plt.show()

结果图:

enter image description here

当我忽略ax.set_extent时,似乎正在绘制Q矢量,只是现在没有地图背景...

no ax.extent

所以我想我的两个问题是:

1)我是否根据GFS数据适当地计算了Q向量?

2)我想密谋什么?

1 个答案:

答案 0 :(得分:2)

所以我认为您可以正确计算Q向量,但是有一个更简单的解决方案。发生错误是因为您传递了dxdy的2D数组,但是字段temperaturepressure_for_calc是3D的。 NumPy不知道应该为每个高度重复dx和dy。您可以通过以下方式完成此操作而无需设置子集:

Q = mpcalc.q_vector(u, v, temperature,pressure_for_calc, dx[None, :], dy[None, :])

这是为dxdy插入一个尺寸为1的尺寸作为第一个尺寸,而其余尺寸不受影响。这样可以使所有内容与其他阵列正确对齐。

就绘图而言,这是经典的CartoPy陷阱。您对quiver的呼叫应类似于:

ax.quiver(lon[lon_slice], lat[lat_slice],
          Q[0][0,lon_slice,lat_slice].m, Q[1][0,lon_slice,lat_slice].m,
          color='k', transform=ccrs.PlateCarree())

请注意要通过transform=ccrs.PlateCarree()的更改。这是告诉CartoPy您要传递给颤动的数据的经度/纬度坐标系。这也假设在此坐标系中正确引用了要绘制的矢量-它们应该是由于您传递了dxdy而得出的。请注意,在这种情况下,由于CartoPy将对向量进行一些重新投影,因此您需要使用mpcalc.lat_lon_grid_deltas()来删除单位。