JiaweiZhuang / xESMF

Universal Regridder for Geospatial Data
http://xesmf.readthedocs.io/
MIT License
269 stars 49 forks source link

Using xESMF with WRFChem #41

Closed zxdawn closed 5 years ago

zxdawn commented 5 years ago

Thank you for your work!

I'm trying to regridding variables in the wrfout* file generated by WRFChem. So, I have modified lon and lat of frontend.py for bilinear regridding.

Here's my plot script and result:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
import xarray as xr
import xesmf as xe

ds = xr.open_dataset("sample")

CG = ds['CG_FLASHCOUNT']
CG_scaled = CG/1E3;
CG_scaled.attrs['units'] = 'kFlashes'

fig = plt.figure(figsize=[8, 4])

proj = ccrs.LambertConformal(central_latitude=20,central_longitude=-95,
                            standard_parallels = (20, 20))

ax = plt.axes(projection=proj)
ax.coastlines()
ax.gridlines(linestyle='--')

nested_grid = {'XLONG': np.linspace(-110, -80, 61),
               'XLAT': np.linspace(20, 50, 61)
              }

regridder_bilinear = xe.Regridder(ds, nested_grid, method='bilinear')

# regridder_bilinear = xe.Regridder(ds, nested_grid, method='conservative')

dr_nested = regridder_bilinear(CG_scaled)
dr_nested.plot(ax=ax, cmap='coolwarm', cbar_kwargs={'label': 'kFlashes'})
ax.set_title('CG_FLASHCOUNT');

plt.show()

image

The coastlines and boundary aren't shown correct.

By the way, I want to use Conservative regridding, but lon_b and lat_b aren't variables in wrfout files. How do you get the value of lon_b and lat_b?

JiaweiZhuang commented 5 years ago

Thanks for the sample file.

The coastlines and boundary aren't shown correct.

Do you mean a plotting issue instead of an xESMF regridding issue?

The same problem will happen for the original data (before regridding). You just need to pass transform=ccrs.PlateCarree() to plot().

%matplotlib inline
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
import xarray as xr

ds = xr.open_dataset("sample")

fig = plt.figure(figsize=[8, 4])
proj = ccrs.LambertConformal(central_latitude=20,central_longitude=-95,
                            standard_parallels = (20, 20))
ax = plt.axes(projection=proj)
ax.coastlines()
ax.gridlines(linestyle='--')
ds['CG_FLASHCOUNT'][0].plot(ax=ax, transform=ccrs.PlateCarree())

wrf_plot

I have modified lon and lat of frontend.py for bilinear regridding.

You can also use ds.rename() to rename coordinates. This should be improved in the future. Welcome to leave comments in #38.

I want to use Conservative regridding, but lon_b and lat_b aren't variables in wrfout files. How do you get the value of lon_b and lat_b?

The safest way is to compute the boundaries manually. Automatically inferring bounds from centers can be quite error-prone, especially for non-orthogonal grids. Alternatively you can try xgcm: https://github.com/JiaweiZhuang/xESMF/issues/13#issuecomment-416947178

zxdawn commented 5 years ago

@JiaweiZhuang Thank you for your help! But, transform=ccrs.PlateCarree() results in false plot.

You can check the script and result generated by Basemap:

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np
import xarray as xr

ds = xr.open_dataset("sample")

fig, ax = plt.subplots(figsize=[8,4])
Lat_min = 20; Lat_max = 50;
Lon_min = -110; Lon_max = -80;

m=Basemap(llcrnrlat=Lat_min,urcrnrlat=Lat_max,\
        llcrnrlon=Lon_min,urcrnrlon=Lon_max,\
        resolution ='l',ax=ax)

parallels = np.arange(-90.,91.,5.)
meridians = np.arange(-180.,181.,10.)
m.drawparallels(parallels,labels=[1,0,0,1],linewidth=0.2,xoffset=0.2,fontsize=12,fontname='Arial')
m.drawmeridians(meridians,labels=[1,0,0,1],linewidth=0.2,yoffset=0.2,fontsize=12,fontname='Arial')
m.drawcoastlines()

p = ax.pcolormesh(ds['XLONG'][0], ds['XLAT'][0], ds['CG_FLASHCOUNT'][0])
clb = fig.colorbar(p,ax=ax)
ax.set_title('CG_FLASHCOUNT')

plt.show()

image

By the way, the setting of Lambert projection in my model is:

 ref_lat                            = 39,    
 ref_lon                            = -95,    
 truelat1                           = 39,    
 truelat2                           = 39,    
 stand_lon                          = -95,    
JiaweiZhuang commented 5 years ago

Also need to pass x='XLONG', y='XLAT' to plot() so that correct coordinates are used for plotting.

%matplotlib inline
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
import xarray as xr

ds = xr.open_dataset("sample")

fig = plt.figure(figsize=[8, 4])
proj = ccrs.LambertConformal(central_latitude=20,central_longitude=-95, standard_parallels = (20, 20))
ax = plt.axes(projection=proj)
ax.coastlines()
ax.gridlines(linestyle='--')
ds['CG_FLASHCOUNT'][0].plot(ax=ax, transform=ccrs.PlateCarree(), x='XLONG', y='XLAT')

wrf_plot

JiaweiZhuang commented 5 years ago

Closing as it is not regridding related.

Welcome to post general questions on https://github.com/geoschem/GEOSChem-python-tutorial, though.