Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d198f62
move exception handling to prevent error from iterating over None
georgemccabe Jan 22, 2026
b846020
Refactor pytests: write output to test/test_output (unless METPLOTPY_…
georgemccabe Jan 22, 2026
d920485
create directory for pointsN file creation so it doesn't fail when di…
georgemccabe Jan 22, 2026
5bdec44
fix bug in write_html and remove_html functions that cause output fil…
georgemccabe Jan 23, 2026
0e1ba74
use os.makedirs to ensure that parent directories are handled
georgemccabe Jan 23, 2026
31f9935
PyCharm files that we may want to ignore
georgemccabe Jan 23, 2026
22418da
create directory before writing file to prevent failure when director…
georgemccabe Jan 23, 2026
8d99261
remove logic that appears to not have any purpose
georgemccabe Jan 23, 2026
85e0cf4
improve logging when verifying config values to alert users which par…
georgemccabe Jan 23, 2026
c8d7bc6
include log output when tests fail for easier debugging, do not creat…
georgemccabe Jan 23, 2026
89fcdd8
delete file that was accidentally committed
georgemccabe Jan 23, 2026
8db8638
add missing import
georgemccabe Jan 23, 2026
acd1283
removed files that were not allowing hovmoeller tests to find top lev…
georgemccabe Jan 23, 2026
f15fea4
only capture INFO or lower logs to avoid excessive DEBUG logs from ex…
georgemccabe Jan 23, 2026
ec77d7b
more updates to tests to write to output directory, removed redundant…
georgemccabe Jan 23, 2026
96d57ff
create directories before writing files to prevent failures when dire…
georgemccabe Jan 23, 2026
7d3c364
update wind_rose and tcmpr_plots tests to write to output directory
georgemccabe Jan 27, 2026
45d3e99
create directory containing output image if it does not already exist…
georgemccabe Jan 27, 2026
17ef868
fix bug in logic to read skew_t data
georgemccabe Jan 27, 2026
2ed2e59
commit PyCharm files to avoid seeing diffs -- will resolve this later
georgemccabe Jan 27, 2026
1e00817
create directory for output file
georgemccabe Jan 27, 2026
3820b3d
remove accidental slash
georgemccabe Jan 27, 2026
cd46593
create test_output directory under wherever the top-level test output…
georgemccabe Jan 27, 2026
6c7d0ec
update scatter, skew_t, and taylor_diagram tests to write to output d…
georgemccabe Jan 27, 2026
923e01a
revise performance_diagram tests to write to output directory
georgemccabe Jan 27, 2026
908ddd6
clean up tests to be consistent with other tests
georgemccabe Jan 27, 2026
05b78c0
update tests to run pytest from top level to run all tests and set PY…
georgemccabe Jan 28, 2026
20c62e1
don't need to set PYTHONPATH because METcalcpy is installed via pip
georgemccabe Jan 28, 2026
52bc09d
use raw string to get rid of SyntaxWarning for invalid escape sequenc…
georgemccabe Jan 28, 2026
e9591bf
remove setup_env fixture because it has fully been replaced by module…
georgemccabe Jan 28, 2026
34751ef
restore file that is referenced in User's Guide
georgemccabe Jan 28, 2026
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
39 changes: 1 addition & 38 deletions .github/workflows/unit_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,41 +70,4 @@ jobs:

- name: Test with pytest
run: |
cd test
cd scatter
pytest test_scatter.py
cd ../bar
pytest test_bar.py
cd ../box
pytest test_box.py
cd ../contour
pytest test_contour.py
cd ../eclv
pytest test_eclv.py
cd ../ens_ss
pytest test_ens_ss.py
cd ../equivalence_testing_bounds
pytest test_equivalence_testing_bounds.py
cd ../line
pytest test_line_groups_plot.py
pytest test_line_plot.py
cd ../mpr_plot
pytest test_mpr_plot.py
cd ../performance_diagram
pytest test_performance_diagram.py
cd ../reliability_diagram
pytest test_reliability_diagram.py
cd ../roc_diagram
pytest test_roc_diagram.py
cd ../taylor_diagram
pytest test_taylor_diagram.py
cd ../wind_rose
pytest test_wind_rose.py
cd ../histogram
pytest test_prob_hist.py
pytest test_rank_hist.py
pytest test_rel_hist.py
cd ../tcmpr_plots
pytest --capture=fd test_tcmpr_plots.py


pytest
2 changes: 1 addition & 1 deletion .idea/METplotpy.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions metplotpy/plots/bar/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,9 @@ def _remove_html(self) -> None:
Removes previously made HTML file.
"""

name_arr = self.get_config_value('plot_filename').split('.')
html_name = name_arr[0] + ".html"
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# remove the old file if it exist
if os.path.exists(html_name):
os.remove(html_name)
Expand All @@ -465,9 +466,8 @@ def write_html(self) -> None:
"""
if self.config_obj.create_html is True:
# construct the file name from plot_filename
name_arr = self.get_config_value('plot_filename').split('.')
name_arr[-1] = 'html'
html_name = ".".join(name_arr)
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# save html
self.figure.write_html(html_name, include_plotlyjs=False)
Expand Down Expand Up @@ -498,10 +498,11 @@ def write_output_file(self) -> None:

filename = filename + '.points1'

# create directory if needed
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, 'w') as f:
for series in self.series_list:
f.write(f"{series.series_points['dbl_med']}\n")
f.close()


def main(config_filename=None):
Expand Down
3 changes: 1 addition & 2 deletions metplotpy/plots/base_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,7 @@ def save_to_file(self):

# Create the directory for the output plot if it doesn't already exist
dirname = os.path.dirname(os.path.abspath(image_name))
if not os.path.exists(dirname):
os.mkdir(dirname)
os.makedirs(dirname, exist_ok=True)
if self.figure:
try:
self.figure.write_image(image_name)
Expand Down
8 changes: 5 additions & 3 deletions metplotpy/plots/box/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,9 +569,8 @@ def write_html(self) -> None:
# is_create = self.config_obj.create_html
if self.config_obj.create_html is True:
# construct the file name from plot_filename
name_arr = self.get_config_value('plot_filename').split('.')
name_arr[-1] = 'html'
html_name = ".".join(name_arr)
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# save html
self.figure.write_html(html_name, include_plotlyjs=False)
Expand Down Expand Up @@ -605,6 +604,9 @@ def write_output_file(self) -> None:
filename = filename + '.points1'
if os.path.exists(filename):
os.remove(filename)
# create directory if needed
os.makedirs(os.path.dirname(filename), exist_ok=True)

for series in self.series_list:
for indy_val in self.config_obj.indy_vals:
if calc_util.is_string_integer(indy_val):
Expand Down
7 changes: 3 additions & 4 deletions metplotpy/plots/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ def _get_show_legend(self) -> list:
"""
show_legend_settings = self.get_config_value('show_legend')

if show_legend_settings is None:
raise ValueError("ERROR: show_legend parameter is not provided.")

# Support all variations of setting the show_legend: '1', 1, "true" (any combination of cases), True (boolean)
updated_show_legend_settings = []
for legend_setting in show_legend_settings:
Expand All @@ -499,10 +502,6 @@ def _get_show_legend(self) -> list:
else:
updated_show_legend_settings.append(int(0))


if show_legend_settings is None:
raise ValueError("ERROR: show_legend parameter is not provided.")

return self.create_list_by_series_ordering(list(updated_show_legend_settings))

def _get_markers(self):
Expand Down
11 changes: 6 additions & 5 deletions metplotpy/plots/contour/contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,9 @@ def _remove_html(self) -> None:
Removes previously made HTML file.
"""

name_arr = self.get_config_value('plot_filename').split('.')
html_name = name_arr[0] + ".html"
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# remove the old file if it exist
if os.path.exists(html_name):
os.remove(html_name)
Expand All @@ -377,9 +378,8 @@ def write_html(self) -> None:
"""
if self.config_obj.create_html is True:
# construct the file name from plot_filename
name_arr = self.get_config_value('plot_filename').split('.')
name_arr[-1] = 'html'
html_name = ".".join(name_arr)
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# save html
self.figure.write_html(html_name, include_plotlyjs=False)
Expand Down Expand Up @@ -408,6 +408,7 @@ def write_output_file(self) -> None:
filename = self.config_obj.points_path + os.path.sep + filename

filename = filename + '.points1'
os.makedirs(os.path.dirname(filename), exist_ok=True)

with open(filename, 'w') as file:
writer = csv.writer(file, delimiter='\t')
Expand Down
1 change: 1 addition & 0 deletions metplotpy/plots/eclv/eclv.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ def write_output_file(self) -> None:
filename = self.config_obj.points_path + os.path.sep + filename

filename = filename + '.points1'
os.makedirs(os.path.dirname(filename), exist_ok=True)

with open(filename, 'w') as file:
writer = csv.writer(file, delimiter='\t')
Expand Down
11 changes: 6 additions & 5 deletions metplotpy/plots/ens_ss/ens_ss.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,9 @@ def _remove_html(self) -> None:
Removes previously made HTML file.
"""

name_arr = self.get_config_value('plot_filename').split('.')
html_name = name_arr[0] + ".html"
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# remove the old file if it exist
if os.path.exists(html_name):
os.remove(html_name)
Expand All @@ -487,9 +488,8 @@ def write_html(self) -> None:
"""
if self.config_obj.create_html is True:
# construct the file name from plot_filename
name_arr = self.get_config_value('plot_filename').split('.')
name_arr[-1] = 'html'
html_name = ".".join(name_arr)
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# save html
self.figure.write_html(html_name, include_plotlyjs=False)
Expand Down Expand Up @@ -525,6 +525,7 @@ def write_output_file(self) -> None:
# filename = 'points'

filename = filename + '.points1'
os.makedirs(os.path.dirname(filename), exist_ok=True)

with open(filename, 'w') as file:
while i < len(self.series_list):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,9 +488,9 @@ def _remove_html(self) -> None:
"""
Removes previously made HTML file.
"""
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

name_arr = self.get_config_value('plot_filename').split('.')
html_name = name_arr[0] + ".html"
# remove the old file if it exist
if os.path.exists(html_name):
os.remove(html_name)
Expand All @@ -504,9 +504,9 @@ def write_html(self) -> None:
self.logger.info(f"Write html file: {datetime.now()}")

if self.config_obj.create_html is True:
# construct the fle name from plot_filename
name_arr = self.get_config_value('plot_filename').split('.')
html_name = name_arr[0] + ".html"
# construct the file name from plot_filename
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# save html
self.figure.write_html(html_name, include_plotlyjs=False)
Expand Down Expand Up @@ -556,6 +556,7 @@ def write_output_file(self) -> None:
filename = self.config_obj.points_path + os.path.sep + filename

filename = filename + '.points1'
os.makedirs(os.path.dirname(filename), exist_ok=True)

# save points
self._save_points(ci_tost_df.values.tolist(), filename)
Expand Down
6 changes: 3 additions & 3 deletions metplotpy/plots/histogram/hist.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,8 @@ def write_html(self) -> None:

if self.config_obj.create_html is True:
# construct the file name from plot_filename
name_arr = self.get_config_value('plot_filename').split('.')
name_arr[-1] = 'html'
html_name = ".".join(name_arr)
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# save html
self.figure.write_html(html_name, include_plotlyjs=False)
Expand Down Expand Up @@ -472,6 +471,7 @@ def write_output_file(self) -> None:
filename = self.config_obj.points_path + os.path.sep + filename

filename = filename + '.points1'
os.makedirs(os.path.dirname(filename), exist_ok=True)

with open(filename, 'w') as file:
for series in self.series_list:
Expand Down
49 changes: 6 additions & 43 deletions metplotpy/plots/histogram_2d/histogram_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,16 @@ def save_to_file(self):
self.logger.info(f"Saving plot to file {image_name}: {datetime.now()} ")
if self.figure:
try:
os.makedirs(os.path.dirname(image_name), exist_ok=True)
self.figure.write_image(image_name)

except FileNotFoundError:
self.logger.error(f"FileNotFoundError: Can't save to file {image_name}")
except ValueError:
except ValueError as err:
self.logger.error(f"ValueError: Some other error occurred "
f"{datetime.now()}")
f"{datetime.now()}: {err}")
else:
self.logger.error(f"The figure was not created. Cannot save file.")
self.logger.error("The figure was not created. Cannot save file.")

self.logger.info(f"Finished saving plot to file: {datetime.now()}")

Expand All @@ -128,46 +129,8 @@ def write_output_file(self):

:return:
"""
self.logger.info(f"Begin writing plot to output file: {datetime.now()}")
self.logger.info(f"No intermediate points1 file created. This plot type is not "
"integrated into METviewer: {datetime.now()}")

# if points_path parameter doesn't exist,
# open file, name it based on the stat_input config setting,
# (the input data file) except replace the .data
# extension with .points1 extension
# otherwise use points_path path
match = re.match(r'(.*)(.data)', self.config_obj.parameters['stat_input'])
if self.config_obj.dump_points_1 is True and match:
filename = match.group(1)
# replace the default path with the custom
if self.config_obj.points_path is not None:
# get the file name
path = filename.split(os.path.sep)
if len(path) > 0:
filename = path[-1]
else:
filename = '.' + os.path.sep
filename = self.config_obj.points_path + os.path.sep + filename

output_file = filename + '.points1'

# make sure this file doesn't already
# exist, delete it if it does
self.logger.info(f"Check if file exists, delete if it does. "
f"{datetime.now()}")
try:
if os.stat(output_file).st_size == 0:
open(output_file, 'a')
else:
os.remove(output_file)
except FileNotFoundError:
# OK if no file was found
self.logger.info(f"FileNotFound while checking if output file exists. "
f" This is OK:{datetime.now()}")
pass

self.logger.info(f"Finished writing plot to output file: {datetime.now()}")
self.logger.info("No intermediate points1 file created. This plot type is not "
f"integrated into METviewer: {datetime.now()}")

def _read_input_data(self):
"""
Expand Down
9 changes: 4 additions & 5 deletions metplotpy/plots/hovmoeller/hovmoeller.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@
__author__ = 'David Fillmore'
__version__ = '0.1.0'

import metcalcpy.util.read_env_vars_in_config

"""
Import standard modules
"""
import os
from datetime import datetime
import getpass
import sys
import yaml

import numpy as np
import xarray as xr
import plotly.graph_objects as go
Expand Down Expand Up @@ -208,8 +207,8 @@ def write_html(self) -> None:
self.logger.info(f"Begin writing html output: {datetime.now()}")
if self.config_obj.create_html is True:
# construct the fle name from plot_filename
name_arr = self.get_config_value('plot_filename').split('.')
html_name = name_arr[0] + ".html"
base_name, _ = os.path.splitext(self.get_config_value('plot_filename'))
html_name = f"{base_name}.html"

# save html
self.figure.write_html(html_name, include_plotlyjs=False)
Expand Down
Loading
Loading