如何使用虹膜模块绘制大气的垂直剖面以及地形? [英] How to plot a vertical section of the atmosphere along with the topography using the Iris module?

查看:59
本文介绍了如何使用虹膜模块绘制大气的垂直剖面以及地形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个netcdf,其风速处于模型级别.在同一netcdf上,我具有每个模型级别的高度.我将netcdf转换为一个立方体,因此每个级别的高度都变成了辅助坐标.我想绘制一个横截面(经度x经度),并希望模型级别遵循地形.我尝试使用Iris模块文档示例( https://scitools.org.uk/iris/docs/latest/examples/General/cross_section.html ),但无法正常工作.

I have a netcdf with wind speed at model levels. On the same netcdf I have the altitude of each model level. I converted netcdf to a cube, so the altitude of each level became an auxiliary coordinate. I would like to plot a cross section (longitude x longitude) and would like the model levels to follow the topography. I tried using the Iris module documentation example (https://scitools.org.uk/iris/docs/latest/examples/General/cross_section.html), but it's not working.

由于我已经掌握了每个海平面相对于海平面的高度,因此我只需要切成垂直部分并进行绘图即可.我尝试遵循该文档示例,但它返回一个错误:ValueError:形状不匹配:无法将对象广播为单个形状

As I already have the altitude of each level relative to sea level I just need to slice into vertical sections and plot. I tried to follow the documentation example, but it is returning an error: ValueError: shape mismatch: objects cannot be broadcast to a single shape

下面是Xarray.Dataset:

Bellow is the Xarray.Dataset:

<xarray.Dataset>
Dimensions:    (latitude: 49, level: 21, longitude: 49)
Coordinates:
  * longitude  (longitude) float32 -52.0 -51.75 -51.5 ... -40.5 -40.25 -40.0
  * latitude   (latitude) float32 -15.0 -15.25 -15.5 ... -26.5 -26.75 -27.0
  * level      (level) int32 1 2 3 4 5 6 7 8 9 10 ... 13 14 15 16 17 18 19 20 21
    time       datetime64[ns] 2017-01-01T10:00:00
    altitude   (level, latitude, longitude) float32 271.3289 ... 1142.3843
Data variables:
    ws         (level, latitude, longitude) float32 0.77094275 ... 14.978188

我将DataArray转换为名为ws_iris的多维数据集:

I converted the DataArray to a cube named ws_iris:

Ws (unknown)    level   latitude    longitude
Shape            21       49              49
Dimension coordinates           
level             x       -              -
latitude        -         x              -
longitude       -         -              x
Auxiliary coordinates           
altitude       x          x              x
Scalar coordinates          
time    2017-01-01 10:00:00

这是我的代码:

import iris
import iris.plot as iplt
import iris.quickplot as qplt
import xarray as xr

ws = xr.open_dataset('ws.nc')

ws_iris = ws.ws.to_iris()

cross_section = next(ws_iris.slices(['longitude', 'level']))

qplt.contourf(cross_section, coords=['longitude', 'altitude'], cmap='viridis', levels=10)

如您所见,我遵循与文档示例相同的步骤(

As you can see I followed the same steps as the documentation example (https://scitools.org.uk/iris/docs/latest/examples/General/cross_section.html)

当我绘制相对于模型级别的经度时,将绘制垂直截面:

When I plot the longitude relative to the model level the vertical section is plotted:

qplt.contourf (cross_section, coords = ['longitude', 'level'], cmap = 'viridis', levels = 10)

但是当我根据海拔绘图时:

But when I plot in relation to altitude:

qplt.contourf (cross_section, coords = ['longitude', 'altitude'], cmap = 'viridis', levels = 10)

我收到以下错误消息:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-35-c93b92f5c581> in <module>
----> 1 qplt.contourf(cross_section, coords=['longitude', 'altitude'], cmap='viridis', levels=10)

~\Anaconda3\lib\site-packages\iris\quickplot.py in contourf(cube, *args, **kwargs)
    202     coords = kwargs.get('coords')
    203     axes = kwargs.get('axes')
--> 204     result = iplt.contourf(cube, *args, **kwargs)
    205     _label_with_points(cube, result, coords=coords, axes=axes)
    206     return result

~\Anaconda3\lib\site-packages\iris\plot.py in contourf(cube, *args, **kwargs)
    937     coords = kwargs.get('coords')
    938     kwargs.setdefault('antialiased', True)
--> 939     result = _draw_2d_from_points('contourf', None, cube, *args, **kwargs)
    940 
    941     # Matplotlib produces visible seams between anti-aliased polygons.

~\Anaconda3\lib\site-packages\iris\plot.py in _draw_2d_from_points(draw_method_name, arg_func, cube, *args, **kwargs)
    516 
    517         u, v = plot_arrays
--> 518         u, v = _broadcast_2d(u, v)
    519 
    520         axes = kwargs.pop('axes', None)

~\Anaconda3\lib\site-packages\iris\plot.py in _broadcast_2d(u, v)
    234     u = np.atleast_2d(u)
    235     v = np.atleast_2d(v.T).T
--> 236     u, v = np.broadcast_arrays(u, v)
    237     return u, v
    238 

~\Anaconda3\lib\site-packages\numpy\lib\stride_tricks.py in broadcast_arrays(*args, **kwargs)
    257     args = [np.array(_m, copy=False, subok=subok) for _m in args]
    258 
--> 259     shape = _broadcast_shape(*args)
    260 
    261     if all(array.shape == shape for array in args):

~\Anaconda3\lib\site-packages\numpy\lib\stride_tricks.py in _broadcast_shape(*args)
    191     # use the old-iterator because np.nditer does not handle size 0 arrays
    192     # consistently
--> 193     b = np.broadcast(*args[:32])
    194     # unfortunately, it cannot handle 32 or more arguments directly
    195     for pos in range(32, len(args), 31):

ValueError: shape mismatch: objects cannot be broadcast to a single shape

有人可以帮助我确定我的代码有什么问题吗?

Can someone help me identify what is wrong with my code.

或者也许有人知道如何制作我想要的图形.

Or maybe someone knows how to make the graph I want otherwise.

非常感谢您.

推荐答案

我不熟悉虹膜,因此我想建议使用 xarray.Datatset 绘制横截面的另一种方法.

I am not familiar with iris so I want to suggest an alternative way to plot cross sections with xarray.Datatset.

Metpy提供了非常有用的功能.对于这个问题.

Metpy provides a very helpful function. for this issue.

https://unidata.github.io/MetPy/latest/api/generated/metpy.interpolate.cross_section.html

否则,您可以使用以下代码来切片数据:

Otherwise you can use following code to slice your datarray:

    points_cross = geodesic(crs_data, start, end, steps)

    data_sliced = data.interp({
        x.name: xr.DataArray(points[:, 0], dims='index', attrs=x.attrs),
        y.name: xr.DataArray(points[:, 1], dims='index', attrs=y.attrs)
    }, method='linear')
    data_sliced.coords['index'] = range(len(points))

使用

def geodesic(crs, start, end, steps):
    r"""Construct a geodesic path between two points.

    This function acts as a wrapper for the geodesic construction available in `pyproj`.

    Parameters
    ----------
    crs: `cartopy.crs`
        Cartopy Coordinate Reference System to use for the output
    start: (2, ) array_like
        A latitude-longitude pair designating the start point of the geodesic (units are
        degrees north and degrees east).
    end: (2, ) array_like
        A latitude-longitude pair designating the end point of the geodesic (units are degrees
        north and degrees east).
    steps: int, optional
        The number of points along the geodesic between the start and the end point
        (including the end points).

    Returns
    -------
    `numpy.ndarray`
        The list of x, y points in the given CRS of length `steps` along the geodesic.

    See Also
    --------
    cross_section

    """
    import cartopy.crs as ccrs
    from pyproj import Geod

    g = Geod(crs.proj4_init)
    geodesic = np.concatenate([
        np.array(start[::-1])[None],
        np.array(g.npts(start[1], start[0], end[1], end[0], steps - 2)),
        np.array(end[::-1])[None]
    ]).transpose()
    points = crs.transform_points(ccrs.Geodetic(), *geodesic)[:, :2]

    return points

这篇关于如何使用虹膜模块绘制大气的垂直剖面以及地形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆