def test_plot_proj(get_test_ds, kwargs, dx, dy): """Run through various options and make sure nothing is broken""" ds = get_test_ds kwargs['dx'] = dx kwargs['dy'] = dy print(ds) if 'blah' in kwargs.values(): with pytest.raises(NotImplementedError): plot_proj_to_latlon_grid(ds.XC, ds.YC, ds.ETAN, **kwargs) else: plot_proj_to_latlon_grid(ds.XC, ds.YC, ds.ETAN, **kwargs) plt.close()
SSH_dir = ECCO_dir + '/nctiles_monthly/SSH/' SSH_dataset = xr.open_dataset(SSH_dir + '/SSH_2010.nc') SSH_dataset.SSH # ``SSH_dataset.SSH`` contains 12 months of data across 13 tiles. # # Let's plot the first time record of this file. # In[5]: SSH = SSH_dataset.SSH.isel(time=0) # mask to nan where hFacC(k=0) = 0 SSH = SSH.where(grid.hFacC.isel(k=0)) fig = plt.figure(figsize=(16, 7)) ecco.plot_proj_to_latlon_grid(grid.XC, grid.YC, SSH, show_colorbar=True) plt.title('SSH [m]') # ### Loading a single ECCOv4 variable NetCDF file using ``load_ecco_var_from_years_nc`` # # We'll now load the same 2010 SSH file using ``load_ecco_var_from_years_nc``. This time we specify the directory containing the NetCDF file, the variable that want to load and the year of interest. # In[6]: # single year: 2010 SSH_dataset_2010 = ecco.load_ecco_var_from_years_nc(SSH_dir, 'SSH', years_to_load=[2010 ]).load() SSH_dataset_2010.attrs = [] SSH_dataset_2010
maskW = ds_ecco.maskW maskS = ds_ecco.maskS plt.figure(figsize=(12,5)) ecco.plot_tiles(dome_maskC+maskC.isel(k=0), cmap='viridis') plt.show() lat_maskW = grid.diff(dome_maskC,'X',boundary='fill') lat_maskS = grid.diff(dome_maskC,'Y',boundary='fill') atl_maskW = ecco.get_basin_mask(basin_name='atlExt', mask=maskW.isel(k=0)) atl_maskS = ecco.get_basin_mask(basin_name='atlExt', mask=maskS.isel(k=0)) plt.figure(figsize=(12,5)) ecco.plot_proj_to_latlon_grid(ds_ecco.XC, ds_ecco.YC, atl_maskW, projection_type='robin', cmap='viridis', user_lon_0=0) plt.show() mvt = ecco.calc_meridional_vol_trsp(ds_ecco,lat_vals=lat, basin_name='atlExt') mht = ecco.calc_meridional_heat_trsp(ds_ecco,lat_vals=lat, basin_name='atlExt') mst = ecco.calc_meridional_salt_trsp(ds_ecco,lat_vals=lat, basin_name='atlExt') plt.figure(figsize=(12,5)) plt.plot(mvt.time,mvt.vol_trsp) plt.ylabel('Meridional Volume Transport (Sv)') plt.show() plt.savefig('mvt_26N_Altlantic.png') plt.figure(figsize=(12,5)) plt.plot(mht.time,mht.heat_trsp) plt.ylabel('Meridional Heat Transport (PW)')
# ## Load ecco-grid information to make a fancier lat-lon plot # # With the longitudes (XC) and latitudes (YC) and the 13 tile ndarray we can plot the field in different geographic projections. See the tutorial on plotting for more examples. # In[6]: ecco_grid_dir = '/Users/ifenty/tmp/nctiles_grid/' ecco_grid = ecco.load_ecco_grid_nc(input_dir, 'ECCO-GRID.nc') # In[7]: plt.figure(figsize=(15,6)); ecco.plot_proj_to_latlon_grid(ecco_grid.XC, ecco_grid.YC, bathy, show_colorbar=True, user_lon_0=-66); # In[8]: plt.figure(figsize=(12,8)); ecco.plot_proj_to_latlon_grid(ecco_grid.XC, ecco_grid.YC, bathy, show_colorbar=True, projection_type='stereo', lat_lim =-45, less_output=True,dx=.25,dy=.25); # ## Convert the ndarray into a DataArray # # Converting the ndarray to a DataArray can be useful for broadcasting operations. One approach is to create the DataArray manually by specifying the names and values of the new dimension coordinates: # In[9]:
# One can also use the gcmfaces function [gcmfaces_calc/gcmfaces_lines_zonal.m](https://github.com/ECCO-GROUP/gcmfaces/blob/master/gcmfaces_calc/gcmfaces_lines_zonal.m). # In[6]: # Get array of 1's at and north of latitude lat = 26 ones = xr.ones_like(ecco_ds.YC) dome_maskC = ones.where(ecco_ds.YC >= lat, 0) # In[7]: plt.figure(figsize=(12, 6)) fig, ax, p, cb = ecco.plot_proj_to_latlon_grid(ecco_ds.XC, ecco_ds.YC, dome_maskC, projection_type='robin', cmap='viridis', user_lon_0=0, show_colorbar=True) ax.add_feature(cart.feature.LAND, facecolor='0.7', zorder=2) plt.show() # Again, if this were a lat/lon grid we could simply take a finite difference in the meridional direction. # The only grid cells with 1's remaining would be at the southern edge of grid cells at approximately 26$^\circ$N. # # However, recall that the LLC grid has a different picture. # In[8]: # Mask masks and add them to ecco_ds
dir_ECCO = '/Volumes/15394457571/ecco_eg' dir_grid = dir_ECCO + '/nctiles_grid' dir_daily = dir_ECCO + '/nctiles_daily/' dir_monthly = dir_ECCO + '/nctiles_monthly/' ## load the grid # grid = xr.open_dataset(dir_grid + '/ECCOv4r3_grid.nc') grid = ecco.load_ecco_grid_nc(dir_grid, 'ECCOv4r3_grid.nc') ecco_ds = ecco.recursive_load_ecco_var_from_years_nc(dir_monthly,\ vars_to_load=['ADVx_TH', 'ADVy_TH', \ 'DFxE_TH', 'DFyE_TH'],\ years_to_load='all',\ dask_chunk=True) ecco_ds = xr.merge([ecco_ds, grid]) grid = ecco.get_llc_grid(ecco_ds) rapid_mask_W, rapid_mask_S = ecco.vector_calc.get_latitude_masks(lat_val=26, yc=ecco_ds.YC, grid=grid) rapid_mask_C = ecco.scalar_calc.get_latitude_mask(lat_val=26, yc=ecco_ds.YC, grid=grid) lat = 26 ones = xr.ones_like(ecco_ds.YC) dome_mask_C = ones.where(ecco_ds.YC >= lat, 0) plt.figure(figsize=(12, 6)) ecco.plot_proj_to_latlon_grid(ecco_ds.XC,ecco_ds.YC,dome_mask_C,\ projection_type='robin',cmap='jet',\ user_lon_0=0,show_colorbar=True,show_grid_lines=True,show_grid_labels=True)
# ### Robinson projection # # First we'll demonstrate the Robinson projection interpolated to a 2x2 degree grid # In[24]: plt.figure(figsize=(12, 6), dpi=90) tmp_plt = ecco_ds.SSH.isel(time=1) tmp_plt = tmp_plt.where(ecco_ds.hFacC.isel(k=0) != 0) ecco.plot_proj_to_latlon_grid(ecco_ds.XC, ecco_ds.YC, tmp_plt, plot_type='pcolormesh', dx=2, dy=2, projection_type='robin', less_output=False) # Setting *lon_0* = 110 or -66 yield a global centering that is is more usesful for plotting ocean basins. # In[25]: plt.figure(figsize=(12, 6), dpi=90) tmp_plt = ecco_ds.SSH.isel(time=1) tmp_plt = tmp_plt.where(ecco_ds.hFacC.isel(k=0) != 0) ecco.plot_proj_to_latlon_grid(ecco_ds.XC, ecco_ds.YC,
for month in range(1,13): t = np.append(t,date(year,month,1).toordinal()) seconds_per_month = 3600 * 24 * (t[1:]-t[0:len(t)-1]) seconds_per_month = xr.DataArray(seconds_per_month,\ coords={'time': G_total_tendency_month.time.values},\ dims='time') G_total_tendency = G_total_tendency_month / seconds_per_month G_total_tendency_mean = G_total_tendency.mean('time') month_length_weights = seconds_per_month / seconds_per_month.sum() G_total_tendency_mean = (G_total_tendency * month_length_weights).sum('time') plt.figure(figsize=(20,8)) ecco.plot_proj_to_latlon_grid(ds_grid.XC, ds_grid.YC,\ G_total_tendency_mean,\ show_colorbar=True,\ cmin=-1e-9, cmax=1e-9, \ cmap=cmocean.cm.balance, user_lon_0=-67,\ dx=map_dx,dy=map_dy) plt.title('Average $\partial \eta / \partial t$ [m/s]', fontsize=20); ETAN_delta_method_2 = ds_ecco_monthly_mean.ETAN.isel(time=-1).values - ds_ecco_monthly_mean.ETAN.isel(time=0).values plt.figure(figsize=(20,8)) ecco.plot_proj_to_latlon_grid(ds_grid.XC, ds_grid.YC,\ ETAN_delta_method_2,\ show_colorbar=True,\ cmin=-1e-9, cmax=1e-9, \ cmap=cmocean.cm.balance, user_lon_0=-67,\ dx=map_dx,dy=map_dy) plt.title('Actual $\Delta \eta$ [m]', fontsize=20);
def global_and_stereo_map(lat, lon, fld, plot_type='pcolormesh', cmap='YlOrRd', title=None, cmin=None, cmax=None, dpi=100, show_colorbar=True): """Generate the Robinson and Arctic/Antarctic plot. Parameters ---------- lat : xarray.DataArray lon : xarray.DataArray fld : xarray.DataArray plot_type : string, optional plot type to use, 'pcolormesh', or 'contourf' cmap : string or colormap object (TBD) cmin : double, optional minimum value for colorbar cmax : double, optional maximum value for colorbar dpi : int, optiopnal plot resolution in dots (pixels) per inch title,show_colorbar figsize? Output ------ """ # to do # -figsize option? # -cmin/cmax defaults handling with plot_proj ... # -colorbar defaults with diverging/sequential # -number of colors in plot # -suppress dask warnings # -get the subplot size "just right" no matter the figsize # -arrows for when colorbar is exceeded # handle colorbar limits cmin, cmax, extend_cbar = set_colorbar_limits(fld, cmin, cmax) # default figsize which seems to work for a laptop screen plt.figure(figsize=(12, 6), dpi=dpi) # the big top global plot fig, ax1, p1, cb1 = ecco.plot_proj_to_latlon_grid(lat, lon, fld, cmap=cmap, plot_type=plot_type, subplot_grid=[2, 1, 1], projection_type='robin', show_colorbar=False, cmin=cmin, cmax=cmax, user_lon_0=0) # Arctic: bottom left fig, ax2, p2, cb2 = ecco.plot_proj_to_latlon_grid(lat, lon, fld, cmap=cmap, plot_type=plot_type, subplot_grid=[2, 2, 3], projection_type='stereo', show_colorbar=False, cmin=cmin, cmax=cmax, lat_lim=50, user_lon_0=0) # ACC: bottom right fig, ax3, p3, cb3 = ecco.plot_proj_to_latlon_grid(lat, lon, fld, cmap=cmap, plot_type=plot_type, subplot_grid=[2, 2, 4], projection_type='stereo', show_colorbar=False, cmin=cmin, cmax=cmax, lat_lim=-40, user_lon_0=180) # Set land color to gray ax1.add_feature(cart.feature.LAND, facecolor='0.7', zorder=2) ax2.add_feature(cart.feature.LAND, facecolor='0.7', zorder=2) ax3.add_feature(cart.feature.LAND, facecolor='0.7', zorder=2) # Make a single title if title is not None: fig.suptitle(title, verticalalignment='top', fontsize=24) # Make an overyling colorbar if show_colorbar: fig.subplots_adjust(right=0.9) cbar_ax = fig.add_axes([0.87, 0.1, 0.025, 0.8]) fig.colorbar(p3, cax=cbar_ax, extend=extend_cbar) return fig, (ax1, ax2, ax3)
# In[23]: MDT_no_spatial_mean.shape # In[24]: plt.figure(figsize=(12,5), dpi= 90) # mask land points to Nan MDT_no_spatial_mean = MDT_no_spatial_mean.where(ocean_mask[0,:] !=0) ecco.plot_proj_to_latlon_grid(ecco_monthly_ds.XC, ecco_monthly_ds.YC, MDT_no_spatial_mean*ocean_mask, user_lon_0=0, plot_type = 'pcolormesh', show_colorbar=True, dx=2,dy=2); plt.title('ECCO v4r3 Mean Dynamic Topography [m]'); # ### Spatial variations of sea level linear trends # # To calculate the linear trend for the each model point we will use on the `polyfit` function of `numpy`. First, define a time variable in years for SSH. # In[25]: days_since_first_record = ((ecco_monthly_ds.time - ecco_monthly_ds.time[0])/(86400e9)).astype(int).values len(days_since_first_record)
def transform_to_model_grid( data_indices_at_model_index_i, num_data_indices_at_model_index_i, day, file, \ sst_field, standard_name, long_name, units,array_precision): # This product's data resolution is 0.25 degrees # So the search should be <= 30km (110 km / degree * 0.25 degrees = 27 km) #interpolation_parameters = 'nearest neighbor, 30km search radius' interpolation_parameters = 'Gaussian weighting, 55km search radius, sigma=25km' # create empty data array sst_DA = make_empty_record(standard_name, long_name, \ units, day, model_grid,array_precision) if isinstance(file, Path) == False: print('could not read file!') else: # read the original data dataset print('reading ', file.name) ds = xr.open_dataset(file, decode_times=True) # extract the original sea ice concentration data orig_data = ds[sst_field].values[0, :] if np.sum(~np.isnan(orig_data)) > 0: # convert to Celsius if sst_field == 'analysed_sst': orig_data -= 273.15 # make a 1D version of the original data orig_data_r = orig_data.ravel() # make an empty array that will hold the data interpolated/averaged to # the grid of the model data_model_projection = np.zeros(model_grid.XC.shape) * np.nan # get a 1D version of data_model_projection dmp_r = data_model_projection.ravel() # loop through every model grid point for i in range(len(dmp_r)): # if the number of *data* points at this model grid point is > 0 if num_data_indices_at_model_index_i[i] > 0: # average those together, put the average in dmp_r dmp_r[i] = orig_data_r[data_indices_at_model_index_i[i]].mean() # put the new SST values into the sst_DA array. # --where the mapped data are not nan, replace the original values # --where they are nan, just leave the original values alone #print ('tmp values shape ', hemi_i, tmp_values.shape) sst_DA.values = np.where(~np.isnan(data_model_projection), \ data_model_projection, sst_DA.values) ##% MASK SST WHERE THERE IS SEA ICE [llo, lla] = np.meshgrid(ds.lon.values, ds.lat.values) llo_ice = llo[np.where(ds.sea_ice_fraction.values[0, :] > 0)] lla_ice = lla[np.where(ds.sea_ice_fraction.values[0, :] > 0)] sea_ice_data = ds.sea_ice_fraction.values[0, :] if np.sum(~np.isnan(sea_ice_data)) > 0: # array of zeros, size of mask tmp = ds.mask[0, :].values * 0 + 1 sea_ice_mask = tmp[np.where(ds.sea_ice_fraction.values[0, :] > 0)] # make a special "swath" for where there is sea ice sea_ice_swath = pr.geometry.SwathDefinition(lons=llo_ice, lats=lla_ice) # project nonzero sea ice concentration values with 50 km to the model grid roi = 50.0e3 # do the actual resampling sea_ice_mask_model_projection = \ pr.kd_tree.resample_nearest(sea_ice_swath, sea_ice_mask, model_swath,\ fill_value=np.nan, \ radius_of_influence=roi) # resape to model grid sea_ice_mask_model_projection = np.reshape(sea_ice_mask_model_projection, \ sst_DA.values.shape) # plt.figure(num=2,clear=True); # ecco.plot_proj_to_latlon_grid(model_grid.XC, model_grid.YC, \ # sea_ice_mask_model_projection, # show_colorbar=True,cmin=0,cmax=2) # mask out places with nonzero sea ice mask sst_DA.values = np.where(sea_ice_mask_model_projection == 1, np.nan, \ sst_DA.values) if 1 == 0: plt.figure(num=3, clear=True) ecco.plot_proj_to_latlon_grid(model_grid.XC, model_grid.YC, \ sst_DA.values[0,:], show_colorbar=True) if 'time_bnds' in ds.keys(): # make time bounds for this record (1 day ) tb, ct = make_time_bounds_from_ds64(ds.time_bnds.values[0, -1], 'AVG_DAY') else: tb, ct = \ make_time_bounds_from_ds64(ds.time.values[0] + np.timedelta64(1,'D'), 'AVG_DAY') # start time is 30 days earlier avg_start_time = sst_DA.time.copy(deep=True) avg_start_time.values[0] = tb[0] avg_end_time = sst_DA.time.copy(deep=True) avg_end_time.values[0] = tb[1] avg_center_time = sst_DA.time.copy(deep=True) avg_center_time.values[0] = ct # we'll make the center of the averaging time sst_DA = sst_DA.assign_coords({'time_start': ('time', avg_start_time)}) sst_DA = sst_DA.assign_coords({'time_end': ('time', avg_end_time)}) # halfway through the approx 1M averaging period. sst_DA.time.values[0] = ct sst_DA.time.attrs['long_name'] = 'center time of 1D averaging period' sst_DA.attrs['original_filename'] = file.name sst_DA.attrs['original_field_name'] = sst_field sst_DA.attrs['interplation_parameters'] = interpolation_parameters sst_DA.attrs['interplation_code'] = 'pyresample' sst_DA.attrs['interpolation_date'] = str(np.datetime64( datetime.now(), 'D')) ## Return the new data array return sst_DA
# ### Plotting the dataset # # Plotting the ECCOv4 fields was covered in an earlier tutorial. Before demonstrating interpolation, we will first plot one of our SSH fields. Take a closer look at the arguments of ``plot_proj_to_latlon_grid``, ``dx=2`` and ``dy=2``. # In[7]: plt.figure(figsize=(12, 6), dpi=90) tmp_plt = ecco_ds.SSH.isel(time=1) tmp_plt = tmp_plt.where(ecco_ds.hFacC.isel(k=0) != 0) ecco.plot_proj_to_latlon_grid(ecco_ds.XC, ecco_ds.YC, tmp_plt, plot_type='pcolormesh', dx=2, dy=2, projection_type='robin', less_output=True) # These ``dx`` and ``dy`` arguments tell the plotting function to interpolate the native grid tiles onto a lat-lon grid with spacing of ``dx`` degrees longitude and ``dy`` degrees latitude. If we reduced ``dx`` and ``dy`` the resulting map would have finer features: Compare with the map when ``dx``=``dy``=0.25 degrees: # In[8]: plt.figure(figsize=(12, 6), dpi=90) tmp_plt = ecco_ds.SSH.isel(time=1) tmp_plt = tmp_plt.where(ecco_ds.hFacC.isel(k=0) != 0) ecco.plot_proj_to_latlon_grid(ecco_ds.XC, ecco_ds.YC,
lat_lon_bounds = np.logical_and(lat_bounds, lon_bounds) # Finally, use **where** to mask out all SSH values that do not fall within our ``lat_lon_bounds`` # In[42]: ssh_da_subset_space = ssh_da.where(lat_lon_bounds, np.nan) # To visualize the SSH in our box we'll use one of our ECCO v4 custom plotting routines (which will be the subject of another tutorial). # # Notice the use of **.sel( )** to subset a single time slice (time=1) for plotting. # In[43]: fig=plt.figure(figsize=(14, 6)) ecco.plot_proj_to_latlon_grid(ecco_ds.XC, ecco_ds.YC, ssh_da_subset_space.isel(time=6), dx=.5, dy=.5,user_lon_0 =0, show_colorbar=True); # ## Conclusion # # You now know several different methods for accessing and subsetting fields in `Dataset` and `DataArray` objects. # # To learn a more about indexing/subsetting methods please refer to the `xarray` manual for indexing methods, http://xarray.pydata.org/en/stable/indexing.html.
## load the grid grid = xr.open_dataset(dir_grid + '/ECCOv4r3_grid.nc') # grid = ecco.load_ecco_grid_nc(dir_grid, 'ECCOv4r3_grid.nc') # Method 1: using xarray.open_dataset dir_ETAN = dir_ECCO + '/nctiles_monthly/ETAN/' dataset_ETAN = xr.open_dataset(dir_ETAN + '/1992/ETAN_1992_01.nc') ## plot ETAN = dataset_ETAN.ETAN.isel(time=0) ## mask to nan where hFacC(k=0) = 0 ETAN = ETAN.where(grid.hFacC.isel(k=0)) fig = plt.figure(figsize=(16,7)) ecco.plot_proj_to_latlon_grid(grid.XC, grid.YC, ETAN, show_colorbar=True, cmin = -1.5, cmax = 1.5) plt.title('SSH (m)') # Method 2, using load_ecco_var_from_years_nc dataset_ETAN = ecco.load_ecco_var_from_years_nc(dir_ETAN,'ETAN',years_to_load=1992).load() dataset_ETAN.attrs = [] dataset_ETAN # Method 3, using dask ## Example 1a: Load two years monthly-mean ECCO fields into memory without Dask dir_mon_mean = dir_ECCO + '/nctiles_monthly/' import time t_0 = time.time() large_subset_no_dask = \ ecco.recursive_load_ecco_var_from_years_nc(dir_mon_mean, \
# the weights sum to 1 print(month_length_weights.sum()) # In[20]: # the weighted mean weights by the length of each month (in seconds) G_total_tendency_mean = (G_total_tendency * month_length_weights).sum('time') # In[21]: plt.figure(figsize=(20, 8)) ecco.plot_proj_to_latlon_grid(ecco_grid.XC, ecco_grid.YC, G_total_tendency_mean, show_colorbar=True, cmin=-1e-9, cmax=1e-9, cmap=cmocean.cm.balance, user_lon_0=-67, dx=map_dx, dy=map_dy) plt.title('Average $\partial \eta / \partial t$ [m/s]', fontsize=20) # ### Total $\Delta \eta$ # # # The time average eta tendency is small, about 1 billionth of a meter per second. The ECCO period is coming up to a billion seconds though... How much did ``ETAN`` change over the analysis period? # In[22]: # the number of seconds in the entire period seconds_in_entire_period = float(ecco_monthly_snaps.time[-1] -
# ssh_arr = ecco_ds.SSH.values # # fig = plt.figure(figsize=(8,6.5)) # plt.imshow(ssh_arr[0,2,:,:],origin='lower') # fig = plt.figure(figsize=(8,6.5)) # plt.imshow(ecco_ds.SSH[0,2,:,:],origin='lower') # # ssh_masked = ecco_ds.SSH.where(grid.hFacC > 0, np.nan) # ssh_masked[0,2,:,:,0].plot(cmap='jet') # # xc = ecco_ds.XC # time = ecco_ds.time for n in range(0, 13): n_tile = n fig = plt.figure(figsize=(14, 6)) ecco.plot_proj_to_latlon_grid(ecco_ds.XC.isel(tile=n_tile),ecco_ds.YC.isel(tile=n_tile), \ ecco_ds.SSH.isel(time = 0,tile=n_tile),\ dx = 0.5, dy=0.5,user_lon_0=0,\ show_colorbar=True,\ show_grid_labels=True,\ show_grid_lines=True) plt.title('tile = ' + str(n)) ssh_da = ecco_ds.SSH lat_bounds = np.logical_and(ssh_da.YC > -20, ssh_da.YC < 60) lon_bounds = np.logical_and(ssh_da.XC > -50, ssh_da.XC < 10) lat_lon_bounds = np.logical_and(lat_bounds, lon_bounds) ssh_da_subset_space = ssh_da.where(lat_lon_bounds, np.nan)
# In[23]: # The weighted mean weights by the length of each month (in seconds) G_total_mean = (G_total * month_length_weights).sum('time') # In[24]: plt.figure(figsize=(15, 15)) for idx, k in enumerate([0, 10, 25]): p = ecco.plot_proj_to_latlon_grid(ecco_grid.XC, ecco_grid.YC, G_total_mean[:, k], show_colorbar=True, cmap='RdBu_r', user_lon_0=-67, dx=2, dy=2, subplot_grid=[3, 1, idx + 1]) p[1].set_title( r'$\overline{G^\theta_{total}}$ at z = %i m (k = %i) [$^\circ$C s$^{-1}$]' % (np.round(-ecco_grid.Z[k].values), k), fontsize=16) # #### Total $\Delta \theta$ # # How much did ``THETA`` change over the analysis period? # In[25]:
# In[7]: maskC_east, maskW_east, maskS_east = ecco.get_section_line_masks(pt1_east,pt2_east,ds) maskC_west, maskW_west, maskS_west = ecco.get_section_line_masks(pt1_west,pt2_west,ds) maskC_tot = (maskC_east+maskC_west).where(maskC_east+maskC_west==1,0) maskW_tot = (maskW_east+maskW_west).where(np.abs(maskW_east)+np.abs(maskW_west)==1,0) maskS_tot = (maskS_east+maskS_west).where(np.abs(maskS_east)+np.abs(maskS_west)==1,0) # In[8]: plt.figure(figsize=(12,6)) fig,ax,p,cb = ecco.plot_proj_to_latlon_grid(ds.XC,ds.YC,maskC_tot,cmap='viridis',projection_type='robin',user_lon_0=0) ax.add_feature(cart.feature.LAND,facecolor='0.7',zorder=2) plt.show() # In[9]: plt.figure(figsize=(8,8)) # use dx=.1, dy=.1 so that plot shows the osnap array as a thin # line. remember, plot_proj_to_latlon_grid first interpolates # the model grid to lat-lon with grid spacing as dx, dy fig,ax,p,cb = ecco.plot_proj_to_latlon_grid(ds.XC, ds.YC, maskC_tot, cmap='viridis', projection_type='PlateCaree', lat_lim=45,dx=.1,dy=.1) ax.add_feature(cart.feature.LAND,facecolor='0.7',zorder=2) ax.set_extent([-80, 20, 40, 80], crs=ccrs.PlateCarree()) plt.show()