如何在xarray中绘制不规则的纬度和经度?

时间:2019-05-22 02:19:53

标签: plot nan latitude-longitude python-xarray

我有一个netcdf文件,其中包含一个月的每日数据。在此文件中,有irregular latitude and longitude个点数据。我想创建一个time[0]或任何时间的数据图,但是结果似乎不正确。如何使用nan-space显示图?

数据文件 https://www.dropbox.com/s/ll35zh4k5ws7nnh/day1.nc?dl=0

代码

import xarray as xr
month_daily1 = xr.open_dataset('/Daily_Month/1/day1.nc')
month_daily1

<xarray.Dataset>
Dimensions:                 (Lat: 175, Lon: 200, time: 31)
Coordinates:
  * time                    (time) datetime64[ns] 2018-01-01 ... 2018-01-31
  * Lat                     (Lat) float64 29.92 29.93 29.94 ... 33.0 33.01 33.02
  * Lon                     (Lon) float64 47.61 47.62 47.63 ... 50.5 50.51 50.52
Data variables:
    Alt                     (time, Lat, Lon) float64 ...
    Temperature             (time, Lat, Lon) float64 ...
    Relative Humidity       (time, Lat, Lon) float64 ...
    Wind speed              (time, Lat, Lon) float64 ...
    Wind direction          (time, Lat, Lon) float64 ...
    Short-wave irradiation  (time, Lat, Lon) float64 ...


# convert kelvin to celsius
data_nonnull = month_daily1.dropna(dim ='time', how='all')
air = data_nonnull.Temperature - 273.15
air


<xarray.DataArray 'Temperature' (time: 31, Lat: 175, Lon: 200)>
array([[[nan, nan, ..., nan, nan],
        [nan, nan, ..., nan, nan],
      ...,

       [[nan, nan, ..., nan, nan],
        [nan, nan, ..., nan, nan],

       [[nan, nan, ..., nan, nan],
        [nan, nan, ..., nan, nan],

Coordinates:
  * time     (time) datetime64[ns] 2018-01-01 2018-01-02 ... 2018-01-31
  * Lat      (Lat) float64 29.92 29.93 29.94 29.95 ... 32.99 33.0 33.01 33.02
  * Lon      (Lon) float64 47.61 47.62 47.63 47.64 ... 50.41 50.5 50.51 50.52


%matplotlib inline

import matplotlib.pyplot as plt
ax = plt.subplot(projection=ccrs.PlateCarree())
air2d = air.isel(time= 0)
air2d.plot.pcolormesh('Lon', 'Lat');

结果 enter image description here

1 个答案:

答案 0 :(得分:1)

我对XArray不太满意,因此建议使用netCDF4模块解决方案:

#!/usr/bin/env ipython
import xarray as xr
import matplotlib as mpl
mpl.use('tkagg')
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
# =======================================================
from netCDF4 import Dataset
ncin=Dataset('day1.nc');
tempin=ncin.variables['Temperature'][0,:,:]- 273.15;
lonin=ncin.variables['Lon'][:];
latin=ncin.variables['Lat'][:];
ncin.close()
# -------------------------------------------------------
from scipy.interpolate import griddata
import numpy as np
kk=np.where(np.isnan(np.array(tempin).flatten())==False)
lonm,latm=np.meshgrid(lonin,latin);
tinterp=griddata((lonm.flatten()[kk],latm.flatten()[kk]),tempin.flatten()[kk],(lonm,latm));

ax = plt.subplot(121,projection=ccrs.PlateCarree())
ax.pcolormesh(lonin,latin,tempin);
ax = plt.subplot(122,projection=ccrs.PlateCarree())
ax.pcolormesh(lonin,latin,tinterp);
plt.show()

最终结果如下所示:左边是原始图像,右边是插值(nan掉落的数字)。 enter image description here

我可以提出一个答案,其中我将XArray和Scipy网格数据结合在一起,因为interpolate_na的工作效果不是很好(用filled_afilled_b查看零件和结果)给我:

#!/usr/bin/env ipython
import xarray as xr
import matplotlib as mpl
mpl.use('tkagg')
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
# =======================================================
month_daily1 = xr.open_dataset('day1.nc')

# convert kelvin to celsius
data_nonnull = month_daily1.dropna(dim ='time', how='all')
air = data_nonnull.Temperature - 273.15
air2d = air.isel(time= 0)
# =======================================================
ax = plt.subplot(121,projection=ccrs.PlateCarree())
air2d.plot.pcolormesh('Lon', 'Lat');
ax = plt.subplot(122,projection=ccrs.PlateCarree())
filled_a=air2d.interpolate_na(dim='Lat');
filled_b=filled_a.interpolate_na(dim='Lon');
filled_c=filled_b.interpolate_na(dim='Lat');
filled_c.plot.pcolormesh('Lon', 'Lat');
plt.show()
# =======================================================
tempin=air2d.values[:];
lonin=air2d.Lon
latin=air2d.Lat
# -------------------------------------------------------
from scipy.interpolate import griddata
import numpy as np
kk=np.where(np.isnan(np.array(tempin).flatten())==False)
lonm,latm=np.meshgrid(lonin,latin);
tinterp=griddata((lonm.flatten()[kk],latm.flatten()[kk]),tempin.flatten()[kk],(lonm,latm));

ax = plt.subplot(121,projection=ccrs.PlateCarree())
ax.pcolormesh(lonin,latin,tempin);
ax = plt.subplot(122,projection=ccrs.PlateCarree())
ax.pcolormesh(lonin,latin,tinterp);
plt.show()