Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more plotting features #5

Open
wants to merge 6 commits into
base: DTC_MPAS
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion ush/plotting/default_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ plot:
#
# figwidth:
# Image width in inches

#
# vmin, vmax:
# By default the color range will be scaled to the max/min values of the plotted data. To use a custom range,
# set vmin and/or vmax

# NOTE: for text fields such as filename, title, etc., some helpful variables are provided that
# you can reference in the text string that will be substituted in the final output:
Expand All @@ -116,6 +119,27 @@ plot:
figwidth: 8
periodic_bdy: False

vmin: null
vmax: null

# Settings for plotting political boundaries. To disable political boundaries, specify "boundaries:" with no options
boundaries:
# Level of political boundaries to plot. Level 0 is national boundaries, Level 1 is sub-national boundaries (e.g.
# states, provinces, etc.), Level 2 is county boundaries (US only); counties require 10m scale
detail: 0
# Scale is the resolution of the plotted boundary dataset. Options are 110m, 50m, and 10m.
scale: 50m

# Settings for plotting coastlines. To disable coastlines, specify "coastlines:" with no options
coastlines:
# Scale is the resolution of the plotted boundary dataset. Options are 110m, 50m, and 10m.
scale: '10m'
# Most standard Matplotlib arguments for shapes will work here, but I haven't figured out good documentation on which.
# The ones listed here work, but likely a lot more customization can happen here.
color: 'black'
facecolor: 'none'
linewidth: 0.5

# Settings for the plot's color bar
colorbar:
# orientation:
Expand Down
30 changes: 22 additions & 8 deletions ush/plotting/plot_mpas_netcdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
print("Importing uxarray; this may take a while...")
import uxarray as ux
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import cartopy.crs as ccrs

import uwtools.api.config as uwconfig

Expand Down Expand Up @@ -99,26 +101,39 @@ def plotit(config_d: dict,uxds: ux.UxDataset,filepath: str) -> None:
for lev in levs:
logging.debug(f"For level {lev}, data slice to plot:\n{sliced[lev]}")
if config_d["plot"]["periodic_bdy"]:
logging.info("Creating polycollection with periodic_bdy=True")
logging.info("NOTE: This option can be very slow for large domains")
pc=sliced[lev].to_polycollection(periodic_elements='split')
else:
pc=sliced[lev].to_polycollection()

pc.set_antialiased(False)

pc.set_cmap(config_d["plot"]["colormap"])
pc.set_clim(config_d["plot"]["vmin"],config_d["plot"]["vmax"])

# logging.info(f"Timer 4 {time.time()-start}")
fig, ax = plt.subplots(1, 1, figsize=(config_d["plot"]["figwidth"], config_d["plot"]["figheight"]),
dpi=config_d["plot"]["dpi"], constrained_layout=True)
# logging.info(f"Timer 5 {time.time()-start}")
dpi=config_d["plot"]["dpi"], constrained_layout=True, subplot_kw=dict(projection=ccrs.PlateCarree()))


ax.set_xlim((config_d["plot"]["lonrange"][0],config_d["plot"]["lonrange"][1]))
ax.set_ylim((config_d["plot"]["latrange"][0],config_d["plot"]["latrange"][1]))

# add geographic features
# ax.add_feature(cfeature.COASTLINE)
# ax.add_feature(cfeature.BORDERS)
#Plot coastlines if requested
if config_d["plot"]["coastlines"]:
ax.add_feature(cfeature.NaturalEarthFeature(category='physical', **config_d["plot"]["coastlines"], name='coastline'))
if config_d["plot"]["boundaries"]:
if config_d["plot"]["boundaries"]["detail"]==0:
name='admin_0_countries'
elif config_d["plot"]["boundaries"]["detail"]==1:
name='admin_1_states_provinces'
elif config_d["plot"]["boundaries"]["detail"]==2:
logging.debug("Counties only available at 10m resolution, overwriting scale=10m")
config_d["plot"]["boundaries"]["scale"]='10m'
name='admin_2_counties'
else:
raise ValueError(f'Invalid value for {config_d["plot"]["boundaries"]["detail"]=}')
ax.add_feature(cfeature.NaturalEarthFeature(category='cultural', scale=config_d["plot"]["boundaries"]["scale"], facecolor='none', linewidth=0.2, name=name))

# Create a dict of substitutable patterns to make string substitutions easier
# using the python string builtin method format_map()
Expand All @@ -144,7 +159,7 @@ def plotit(config_d: dict,uxds: ux.UxDataset,filepath: str) -> None:
cbar = plt.colorbar(coll,ax=ax,orientation=cb["orientation"])
if cb.get("label"):
cbar.set_label(cb["label"].format_map(patterns))

outfile=config_d["plot"]["filename"].format_map(patterns)
# Make sure any subdirectories exist before we try to write the file
logging.debug(f"Saving plot {outfile}")
Expand Down Expand Up @@ -273,6 +288,5 @@ def setup_config(config: str, default: str="default_options.yaml") -> dict:
# Open specified file and load dataset
dataset=load_dataset(f,expt_config["data"]["gridfile"])


# Make the plots!
plotit(expt_config,dataset,f)