Как получить данные об относительной влажности isobari c в виде двумерного массива? - PullRequest
1 голос
/ 24 марта 2020

Я пытаюсь создать контурную диаграмму относительной влажности при постоянном уровне давления (500 гПа), аналогичную описанной в руководстве MetPy xarray . Я получил данные с помощью пакета Siphon и проанализировал их в массив, который кажется двумерным с фиксированными временем и высотой и изменением широты / долготы:

<xarray.DataArray 'relative_humidity' (time: 1, lat: 141, lon: 121)>
array([[[100. , 100. , ...,  48.5,  48.1],
        [100. , 100. , ...,  42.8,  41.1],
        ...,
        [  9.5,   9.4, ...,  20.7,  18.7],
        [  9.5,   9.9, ...,  23.8,  21.1]]], dtype=float32)
Coordinates:
    reftime   (time) datetime64[ns] 2020-03-24T12:00:00
  * time      (time) datetime64[ns] 2020-03-24T18:00:00
    isobaric  float32 50000.0
  * lat       (lat) float32 55.0 54.75 54.5 54.25 54.0 ... 20.75 20.5 20.25 20.0
  * lon       (lon) float32 270.0 270.25 270.5 270.75 ... 299.5 299.75 300.0
    crs       object Projection: latitude_longitude

Чтобы получить В этом массиве я использовал код:

data = ncss.get_data(query)

#Parse data using MetPy
ds = xr.open_dataset(NetCDF4DataStore(data))
data = ds.metpy.parse_cf()

#Rename variables to useful things
data = data.rename({
    'Vertical_velocity_pressure_isobaric': 'omega',
    'Relative_humidity_isobaric': 'relative_humidity',
    'Temperature_isobaric': 'temperature',
    'u-component_of_wind_isobaric': 'u',
    'v-component_of_wind_isobaric': 'v',
    'Geopotential_height_isobaric': 'height'
})

#Get data specific to 500mb
zH5 = data['height'].metpy.sel(vertical=850 * units.hPa)
zH5_crs = zH5.metpy.cartopy_crs

#Define coordinates
vertical, = data['temperature'].metpy.coordinates('vertical')
time = data['temperature'].metpy.time
x, y = data['height'].metpy.coordinates('x', 'y')
lat, lon = xr.broadcast(y, x)

#Create relative humidity array
rel_hum = data['relative_humidity'].metpy.sel(vertical=500*units.hPa)

Однако, когда я go строю RH как заполненные контуры:

rh = ax.contourf(x, y, rel_hum, levels=[70, 80, 90, 100], colors=['#99ff00', '#00ff00', '#00cc00'])

Я получаю сообщение об ошибке:

TypeError: Input z must be 2D, not 3D

После прочтения другого SO сообщения о похожей проблеме я понимаю почему третий параметр функции контура должен быть двумерным массивом, но я не уверен, почему моя процедура здесь (которая очень близко имитирует учебный код xarray из документации MetPy ) не дает такого массива, который можно построить.

1 Ответ

0 голосов
/ 24 марта 2020

Так что, хотя кажется, что ваши данные являются двухмерными, поскольку у вас есть только одно время, на основе этого вывода:

<xarray.DataArray 'relative_humidity' (time: 1, lat: 141, lon: 121)>

данные по-прежнему считаются трехмерными, поскольку у вас все еще есть измерение времени (даже хотя это размер 1). Одним из способов является изменение вашего звонка на .sel для выбора определенного времени (или добавление еще одного звонка к .sel для этого).

Мой предпочтительный способ решить эту проблему - использовать вызов .squeeze(). squeeze() - это метод удаления всех измерений размера 1, решающий эту очень частую проблему наличия некоторых посторонних измерений (которые фактически не добавляют к общему количеству элементов в массиве):

rel_hum = data['relative_humidity'].metpy.sel(vertical=500*units.hPa).squeeze()

Это также приводит к тому, что если у вас действительно есть 3D-данные, это не изменит форму. В зависимости от вашего приложения это может или не может быть хорошей вещью. (Если это плохо, лучше использовать .sel для выбора времени.)

...