Skip to content
Snippets Groups Projects

Part 1 of plotting fixes

Merged Fraser William Goldsworth requested to merge m301014/pyicon:plotting-fixes into master
1 file
+ 170
27
Compare changes
  • Side-by-side
  • Inline
+ 170
27
import sys, glob, os
import json
from pathlib import Path
# --- calculations
import numpy as np
from scipy import interpolate
@@ -1898,6 +1899,115 @@ def plot(data,
# --- original grid
lonlat_for_mask=False,
):
"""plot map of data
Parameters
----------
data : xr.DataArray
data to be
Plot : pyicon.Plot, optional
plotting canvas to draw on, by default None
ax : matplotlib.axes, optional
axis to plot on to , by default None
cax : matplotlib.axes, optional
axis to plot colorbar on, by default None
asp : float, optional
aspect ratio, by default None
fig_size_fac : float, optional
_description_, by default 2.0
mask_data : bool, optional
mask data where data = 0 (NaN value in ICON), by default True
logplot : bool, optional
logarithmic colormap, by default False
lon_reg : _type_, optional
longitude range to plot, by default None
lat_reg : _type_, optional
latitudes range to plot, by default None
central_longitude : str or float, optional
central longitude of plot, by default 'auto'
clim : str or (float, float), optional
colorbar limits, by default 'auto'
cmap : str or colormap, optional
colormap to use, by default 'auto'
conts : _type_, optional
_description_, by default None
contfs : _type_, optional
_description_, by default None
clevs : _type_, optional
_description_, by default None
use_pcol_or_contf : bool, optional
_description_, by default True
contcolor : str, optional
colour of contours, by default 'k'
cincr : float, optional
_description_, by default -1.0
clabel : bool, optional
whether to label contours, by default False
cbticks : str or list, optional
ticks for colorbar, by default 'auto'
xlabel : str, optional
label for x-axis, by default ''
ylabel : str, optional
label fo y-axis, by default ''
xticks : str or list, optional
tick labels for x-axis, by default 'auto'
yticks : str or list, optional
tick labels for y-axis, by default 'auto'
template : str, optional
_description_, by default 'none'
cbar_str : str, optional
label for colorbar, by default 'auto'
cbar_pos : str, optional
position of colorbar, by default 'bottom'
title_right : str, optional
title for rhs of plot, by default 'auto'
title_left : str, optional
title for lhs of plot, by default 'auto'
title_center : str, optional
title for centre of plot, by default 'auto'
projection : str, optional
projection for map, by default 'pc'
coastlines_color : str, optional
colour of coastlines, by default 'k'
land_facecolor : str, optional
colour of land, by default '0.7'
axes_facecolor : str, optional
colour of background axes, by default '0.7'
noland : bool, optional
whether to not plot land, by default False
do_plot_settings : bool, optional
whether to apply defauly plot settings, by default True
do_xyticks : bool, optional
_description_, by default True
do_gridlines : bool, optional
whether to plot gridlindes, by default False
gname : str, optional
name of the grid the data is on, by default 'auto'. Typically the name
of a subdirectory of pyicon.params["path_grid"].
fpath_tgrid : str, optional
path to the triangulation grid, by default 'auto'.
plot_method : "nn" or "tgrid", optional
whether to use perform nearest neighbour (nn) interpolation or plot on
the native triangular grid (tgrid), by default 'nn'
res : float, optional
resolution for healpix grids, by default 0.3
fpath_ckdtree : str, optional
path to the ckdtree, by default 'auto'
coordinates : str, optional
the coordinates of the variable to plotted, by default 'clat clon'.
Typically set to "xlon xlat" where x is either "c", "e" or "v" for cell,
edge or vertex points.
lonlat_for_mask : bool, optional
_description_, by default False
Returns
-------
ax : matplotlib.axes
axes that have been plotted to
hm : _type_
_description_
"""
# --- derive plot boundaries
@@ -1943,37 +2053,41 @@ def plot(data,
# --- identify grid file names and paths
path_grid = params['path_grid']
if gname=='auto':
try:
Dgrid = identify_grid(data, path_grid)
except:
# This doesn't always work, lets try another approach
try:
Dgrid = identify_grid(data, path_grid)
gname = Dgrid['name']
Dgrid = identify_grid(
data, path_grid, uuidOfHGrid=data.attrs['uuidOfHGrid']
)
except:
try:
Dgrid = identify_grid(data, path_grid, uuidOfHGrid=data.attrs['uuidOfHGrid'])
gname = Dgrid['name']
except:
gname = 'none'
if fpath_tgrid=='auto':
Dgrid = dict()
if gname == "auto":
try:
Dgrid = identify_grid(data, path_grid)
fpath_tgrid = Dgrid['fpath_grid']
except:
fpath_tgrid = 'from_file'
if fpath_ckdtree=='auto':
fpath_ckdtree = f'{path_grid}/{gname}/ckdtree/rectgrids/{gname}_res{res:3.2f}_180W-180E_90S-90N.nc'
if grid_type=='auto':
if Dgrid["name"].startswith("healpix"):
gname = Dgrid["name"]
except KeyError:
gname = "none"
if fpath_tgrid == "auto":
try:
fpath_tgrid = Dgrid["fpath_grid"]
except KeyError:
fpath_tgrid = "from_file"
if grid_type == 'auto':
if gname.startswith("healpix"):
grid_type = 'healpix'
else:
grid_type = 'native'
if fpath_ckdtree == 'auto':
fpath_ckdtree = f'{path_grid}/{gname}/ckdtree/rectgrids/{gname}_res{res:3.2f}_180W-180E_90S-90N.nc'
# --- rename dimensions
if 'cells' in data.dims:
data = data.rename(cells='ncells')
#for dim in data.dims:
# if dim.startswith('layers'):
# data = data.rename({dim: 'depth'})
# --- infer depth name
depth_name = identify_depth_name(data)
@@ -1985,20 +2099,45 @@ def plot(data,
# ---
if data.ndim!=1:
raise ValueError(f'::: Error: Wrong dimension of data: {data.dims}.')
#if 'grid_mapping' in list(data.attrs):
# plot_method = 'healpix'
# --- interpolate and cut to region
if grid_type=='native' and plot_method=='nn':
datai = interp_to_rectgrid_xr(data.compute(), fpath_ckdtree, lon_reg=lon_reg, lat_reg=lat_reg, coordinates=coordinates)
if grid_type == 'native' and plot_method == 'nn':
# We need fpath_ckdtree so check it is there.
if not Path(fpath_ckdtree).exists():
if gname == "none":
raise FileNotFoundError(
f"Unable to find file `fpath_ckdtree={fpath_ckdtree}`. \
This may be because `gname='none'`. Try either setting \
`gname` explicitly or `fpath_ckdtree` explicitly. `gname` \
typically takes the name of a subdirectory of the folder \
{params['path_grid']}"
)
else:
raise FileNotFoundError(
f"Unable to find file `fpath_ckdtree={fpath_ckdtree}`. \
Try setting `fpath_ckdtree` explicitly."
)
datai = interp_to_rectgrid_xr(
data.compute(), fpath_ckdtree,
lon_reg=lon_reg, lat_reg=lat_reg, coordinates=coordinates
)
lon = datai.lon
lat = datai.lat
elif grid_type=='native' and plot_method=='tgrid':
print('Deriving triangulation object, this can take a while...')
if fpath_tgrid != 'from_file':
ds_tgrid = xr.open_dataset(fpath_tgrid)
else:
raise NotImplementedError(
"Function not yet ready for calling with \
`fpath_tgrid='from_file'`, `grid_type='native'` and \
`plot_method='tgrid`"
)
# In the below code it isn't clear what ds should be?
ds_tgrid = xr.Dataset()
ntr = ds.clon.size
vlon = ds.clon_bnds.data.reshape(ntr*3)
@@ -2027,6 +2166,11 @@ def plot(data,
datai = hp_to_rectgrid(data, lon_reg=lon_reg, lat_reg=lat_reg, res=res)
lon = datai.lon
lat = datai.lat
else:
raise ValueError(
"Invalid combination of `grid_type` and `plot_method` \
arguments."
)
# --- title, colorbar, and x/y label strings
if cbar_str=='auto':
@@ -2050,7 +2194,6 @@ def plot(data,
cbar_str = f'{data.name}'
if (title_right=='auto') and ('time' in data.coords):
tstr = str(data.time.data)
#tstr = tstr.split('T')[0].replace('-', '')+'T'+tstr.split('T')[1].split('.')[0].replace(':','')+'Z'
tstr = tstr.split('.')[0]
title_right = tstr
elif (title_right=='full_time') and ('time' in data.dims):
Loading