Skip to content

Commit

Permalink
Bug fix and feature update - version 0.9.5
Browse files Browse the repository at this point in the history
Fixed bug that has 3D data for lat & lon coordinate

Fixed bug that prevented plotting on domain 2 wrfout file

Now user can provide custom contour level using '--clevels'  command line option
  • Loading branch information
wxguy committed Feb 22, 2023
1 parent 2b64b45 commit bac5081
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ instance/

# Sphinx documentation
docs/_build/
docs/pdf/

# PyBuilder
.pybuilder/
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ wrfplot --version

### Linux Only

You must have at least `Ubuntu 22.04` or above for this to work. There is no additional packages or admin rights are required to install this package. Go to https://github.com/wxguy/wrfplot/releases and look for latest release. The Linux installer will have name `wrfplot-linux-64bit.run`. Click on the link and download it to local disk. Thereafter execute the below command (assuming that the Linux installer is downloaded at `~/Downloads`):
You must have at least `Ubuntu 22.04` , `Red Hat 8.x` or above for this to work. There is no additional packages or admin rights are required to install this package. Go to https://github.com/wxguy/wrfplot/releases and look for latest release. The Linux installer will have name `wrfplot-linux-64bit.run`. Click on the link and download it to local disk. Thereafter execute the below command (assuming that the Linux installer is downloaded at `~/Downloads`):

```
bash ~/Downloads/wrfplot-linux-64bit.run
Expand Down
2 changes: 1 addition & 1 deletion installer.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
; Define the path to directory where Nutika put all our application files and directories
!define PY_APP_DIR "build\windows\wrfplot"
!define PRODUCT_NAME "wrfplot"
!define PRODUCT_VERSION "0.3.1"
!define PRODUCT_VERSION "0.9.5"
!define BITNESS "64"
!define ARCH_TAG ".amd64"
!define INSTALLER_NAME "wrfplot-windows-64bit.exe"
Expand Down
40 changes: 40 additions & 0 deletions wrfplot/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,46 @@ def validate_ulevels(ulevels):
return None


def validate_clevels(clevels):
"""Validate user provided contour levels
Args:
ulevels (list or int): list or no of levels provided by user
Results:
list or int: List of filtered contour levels. False is returned if invalid levels are provided.
"""
filtered_clevels = []
if ',' not in clevels:
if clevels.isdigit():
if int(clevels) > 12:
print("\nContour levels number must be kept maximum as 12. Defaulting to " , utils.quote("12"))
return "12"
else:
print("\nUsing user provided upper clevel : " + utils.quote(clevels))
return clevels
elif isinstance(clevels, str):
print("\nContour level can not have string in it. Omitting " + utils.quote(clevels))
return False
else:
for level in clevels.split(','):
if level.strip().isdigit():
if int(level) in filtered_clevels:
print("\nContour level", level, "already exist. Not repeating it.")
else:
filtered_clevels.append(int(level))
elif isinstance(level, str):
print("Contour levels can not have string in it. Omitting " + utils.quote(level))

if len(filtered_clevels) == 0:
print("Reverting to automatic contour levels supported by wrfplot.")
return False
else:
output_str_lst = [str(x) for x in filtered_clevels]
print("Using user provided contour levels : " + utils.quote(",".join(sorted(output_str_lst))))
return sorted(filtered_clevels)



def validate_gif_speed(seconds):
"""Validate user provided gif animation speed
Expand Down
10 changes: 7 additions & 3 deletions wrfplot/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(
u_level=None,
proj=None,
cmap=None,
clevels=None,
clevels=False,
fig_format="png",
output_dir=None,
dpi=150,
Expand Down Expand Up @@ -161,7 +161,11 @@ def plot_var(self):

def get_clevels(self):
"""Get contour levels"""
if self.clevels == "auto":
if self.clevels is not False and isinstance (self.clevels, list):
return self.clevels
elif self.clevels is not False and isinstance (self.clevels, str):
self.clevels = utils.get_auto_clevel(self.data, scale=int(self.clevels))
elif self.clevels == "auto":
self.clevels = utils.get_auto_clevel(self.data)

def plot_title(self):
Expand Down Expand Up @@ -233,7 +237,7 @@ def plot_cbar(self):

def plot_data(self):
"""Plot 2D data on a Map"""
# We need to normalise the colour map with data levels. Otherwise, colourmap will be squed
# We need to normalise the colour map with data levels. Otherwise, colourmap will be skewed
# SLP data does not require to have colour fill
if self.var_name == "slp":
self.cs = plt.contour(
Expand Down
35 changes: 27 additions & 8 deletions wrfplot/wrfplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class Wrfplot(object):
"""Main class to deal with WRF input data"""

def __init__(
self, input_path, output_path=None, variables=[], ulevels=None, dpi=150, cmap=False, animation=False, animation_speed=0.5,
self, input_path, output_path=None, variables=[], ulevels=None, dpi=150, cmap=False, animation=False, animation_speed=0.5, clevels=False,
):
self.input_file = input_path
self.nc_fh = None
Expand All @@ -93,7 +93,7 @@ def __init__(
self.ulevels = ulevels
self.ulevel = None
self.proj = None
self.clevels = []
# self.clevels = []
self.cycle = None
self.file = fileio.FileIO(self.input_file)
self.config = ConfigParser()
Expand All @@ -106,6 +106,7 @@ def __init__(
self.rainnc = None
self.animation = animation
self.speed = animation_speed
self.clevels = clevels

def read_file(self, input_path):
"""Read input NetCDF file
Expand Down Expand Up @@ -191,8 +192,14 @@ def read_data(self, var):
self.var_data = getvar(self.nc_fh, var, ALL_TIMES)

def read_latlons(self):
"""Extract lat & lon data and update ``self.lats`` and ``self.lons`` instance variables accordingly"""
self.lats, self.lons = latlon_coords(self.var_data)
"""Extract lat & lon data and update ``self.lats`` and ``self.lons`` variables accordingly"""
lats, lons = latlon_coords(self.var_data)
if lats.ndim == 3:
self.lats = lats[0]
self.lons = lons[0]
else:
self.lats = lats
self.lons = lons

def plot_variables(self):
"""A wrapper function to redirect plotting to surface and upper air variables to respective function"""
Expand Down Expand Up @@ -264,7 +271,7 @@ def plot_sfc(self):
if self.var == "slp":
self.var_data = smooth2d(self.var_data, 3, cenweight=4)
self.clevels = utils.get_auto_clevel(self.var_data, slp=True)
else:
elif self.clevels is False:
self.clevels = json.loads(self.config.get(self.var, "clevels"))

if data_plot is None:
Expand Down Expand Up @@ -436,7 +443,12 @@ def get_unit(self):
def get_proj(self):
"""Get projection details from data extracted"""
if self.proj is None:
self.proj = get_cartopy(self.var_data)
if self.var_data.ndim == 3:
self.proj = get_cartopy(self.var_data[0])
elif self.var_data.ndim == 4:
self.proj = get_cartopy(self.var_data[0, 0])
else:
self.proj = get_cartopy(self.var_data)


def _praser():
Expand Down Expand Up @@ -487,6 +499,13 @@ def _praser():
default=False,
help="Valid colormap name to fill colors. Use '--list-cmaps' option to see list of supported colormaps. Must have minimum 11 colors, else will lead to error.",
)
parser.add_argument(
"--clevels",
metavar="<contour-levels>",
type=arguments.validate_clevels,
default=False,
help="Provide custom contour level(s) to highlight data. Levels are to be in ascending order and seperated by ',' i.e., '24,26,28'. If single value is provided, clevels will be automatically calculated.",
)
parser.add_argument(
"--dpi",
metavar="<value>",
Expand Down Expand Up @@ -525,13 +544,13 @@ def main():
sys.exit(print(__version__))
elif not all([args.input, args.vars, args.output]):
sys.exit(
"You must provide path to WRF model output file using '--input' option, output directory for saving image files using '--output' option and must provide at least one variable name using '--var' option to process.\nTypical usage will be \"wrfplot --input filename' --output 'path/to/output/dir' --var 'slp'\""
"You must provide path to WRF model output file using '--input' option, output directory for saving image files using '--output' option and must provide at least one variable name using '--vars' option to process.\nTypical usage will be \"wrfplot --input filename' --output 'path/to/output/dir' --vars 'slp'\""
)
elif all([args.input, args.vars, args.output]):
file = fileio.FileIO(args.input)
if file.is_wrf():
wrfplt = Wrfplot(
input_path=args.input, output_path=args.output, dpi=args.dpi, cmap=args.cmap, ulevels=args.ulevels, animation=args.gif, animation_speed=args.gif_speed
input_path=args.input, output_path=args.output, dpi=args.dpi, cmap=args.cmap, ulevels=args.ulevels, animation=args.gif, animation_speed=args.gif_speed, clevels=args.clevels
)
try:
wrfplt.read_file(args.input)
Expand Down

0 comments on commit bac5081

Please sign in to comment.