Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0e23351
Issue #556 this is the original BasePlot class, containing Plotly and…
bikegeek Jan 21, 2026
df0dc9e
Per #556, create _plotly versions of util.py, constants.py, and confi…
georgemccabe Jan 22, 2026
1a38b17
Do not use util.apply_weight_style -- it adds html which isn't used b…
georgemccabe Jan 22, 2026
036903f
Merge branch 'feature_555_replace_plotly' into feature_556_copy_base_…
georgemccabe Jan 28, 2026
ceb5802
add fix for creating parent directories to plotly version of base plot
georgemccabe Jan 28, 2026
18aa26b
Merge branch 'develop' of https://github.com/dtcenter/METplotpy into …
bikegeek Feb 2, 2026
69d5b38
hotfix: fix handling of missing data by changing replace value from s…
georgemccabe Feb 3, 2026
150a3c7
hotfix: remove string representing color that causes UserWarning and …
georgemccabe Feb 3, 2026
6fe7771
Merge branch 'develop' of https://github.com/dtcenter/METplotpy into …
bikegeek Feb 4, 2026
a9faf5b
merged develop and resolved conflicts
georgemccabe Feb 4, 2026
74fc7aa
Merge branch 'feature_555_replace_plotly' into feature_556_copy_base_…
georgemccabe Feb 5, 2026
b664740
remove more plotly-specific stuff from matplotlib version
georgemccabe Feb 5, 2026
f8d47f5
Merge branch 'feature_556_copy_base_and_common_functionality' of http…
bikegeek Feb 5, 2026
c7cae0c
Merge branch 'develop' of https://github.com/dtcenter/METplotpy into …
bikegeek Feb 5, 2026
07cf5bd
Issue #556 Remove any Plotly-specific code and imports. Update copyr…
bikegeek Feb 5, 2026
fd6e39c
Merge branch 'feature_555_replace_plotly' into feature_556_copy_base_…
georgemccabe Feb 6, 2026
b616fcd
clean up logic to calculate plot dimensions to always use matplotlib …
georgemccabe Feb 6, 2026
3bc22fd
remove plotly-specific variables and update incorrect imports to use …
georgemccabe Feb 6, 2026
fda41c5
resolve SonarQube complaints and clean up logic
georgemccabe Feb 6, 2026
392ee95
more SonarQube issues resolved
georgemccabe Feb 6, 2026
0ab7528
Issue #556 Updates to base_plot to support title,caption, x-axis labe…
bikegeek Feb 6, 2026
c8bb31d
Merge branch 'feature_556_copy_base_and_common_functionality' of http…
bikegeek Feb 7, 2026
14469fb
Issue #556 use the get_weights_size_style() from base_plot.py to plot…
bikegeek Feb 7, 2026
ad3c90f
Fixed comment to remove Plotly reference in
bikegeek Feb 7, 2026
1c0d319
Revert to previous version, which already removed Plotly-specific cod…
bikegeek Feb 7, 2026
6f68ae8
Added TODO for code that should be removed when all plots have been m…
bikegeek Feb 7, 2026
f92761a
Added TODO comments to identify code that will need to be removed whe…
bikegeek Feb 7, 2026
b7e827d
remove plotly variables from matplotlib version
georgemccabe Feb 9, 2026
4467a90
remove unneeded import
georgemccabe Feb 9, 2026
f10a8a0
Per #558, refactor bar plot to use matplotlib instead of plotly
georgemccabe Feb 10, 2026
5c71d9d
Revert back to using _get_fcst_vars to avoid breaking things, but add…
georgemccabe Feb 17, 2026
9e0979f
added default widths of some matplotlib shapes
georgemccabe Feb 17, 2026
d1477d6
added back _get_fcst_vars override to avoid breaking things for now. …
georgemccabe Feb 17, 2026
8917e01
move more common functionality into the base plot class so it can be …
georgemccabe Feb 17, 2026
021f923
Progress towards creating box plots using matplotlib. Adjustment is s…
georgemccabe Feb 17, 2026
a4fcdd9
fix incorrectly formatted show_legend values that are interpreted as …
georgemccabe Feb 17, 2026
5f81621
handle multiple test_*.py files in a test directory by checking the n…
georgemccabe Feb 17, 2026
77b09e2
move caption_weight handling to base config
georgemccabe Feb 24, 2026
3faba15
progress towards getting revision_box working utilizing as much from …
georgemccabe Feb 24, 2026
dae5318
merged feature_555_remove_plotly and resolved conflicts
georgemccabe Feb 26, 2026
7bbe59e
move default config seetings that are not set by all of the plots to …
georgemccabe Feb 27, 2026
2c51ea4
Per #558, update histogram plot to use matplotlib instead of plotly
georgemccabe Feb 27, 2026
369dad3
add support for custom lines
georgemccabe Feb 27, 2026
d35fe90
fix number of columns in legend to match original R plot
georgemccabe Feb 27, 2026
4f33a79
turn off grid to match original R plot
georgemccabe Feb 27, 2026
fc2eec7
Refactored config consistency checking to be consistent across multip…
georgemccabe Feb 27, 2026
58eb4dd
after updating config consistency check logic, fix incorrect yaml val…
georgemccabe Feb 27, 2026
94383dd
added mean line, adjusted median line, and added logic to more closel…
georgemccabe Feb 27, 2026
c922238
adjusted config value to stretch whisker to outlier point to more clo…
georgemccabe Feb 27, 2026
3879114
improve handling of situation when fcst vars are not set in config
georgemccabe Feb 27, 2026
13cb39d
use explicit function to get fcst var keys instead of dict
georgemccabe Feb 27, 2026
53140c3
adjust settings for whis and showfliers to more closely match the plo…
georgemccabe Mar 2, 2026
ef51ddf
change value back to original because plot should create the same for…
georgemccabe Mar 2, 2026
d0e3b56
updates to get revision box plots to render (more) correctly and so t…
georgemccabe Mar 2, 2026
63e91a7
remove commented code and out-of-date comments
georgemccabe Mar 2, 2026
67c5a3f
test copying files with differences to a diff artifact
georgemccabe Mar 3, 2026
1523642
create diff artifact even when the step before it fails due to diffs
georgemccabe Mar 3, 2026
e53688e
fix issues with hovmoeller test plot by closing global matplotlib plt…
georgemccabe Mar 4, 2026
db8b376
Update matplotlib plots to call self.save_to_file instead of plt.save…
georgemccabe Mar 5, 2026
ad9f086
use develop version of diff util after changes were merged
georgemccabe Mar 5, 2026
f0707c9
fix incorrect location of caption by overriding _add_caption function…
georgemccabe Mar 6, 2026
6086c88
clean up
georgemccabe Mar 6, 2026
6b5ac45
Apply suggestion from @bikegeek
georgemccabe Mar 9, 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
11 changes: 10 additions & 1 deletion .github/workflows/unit_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,24 @@ jobs:
# Note: upload-artifact v4 nested paths differently, usually named by 'name' provided in upload
OUTPUT_DIR="${{ runner.workspace }}/artifacts/test_output_${OUTPUT_BRANCH}_${{ matrix.python-version }}"
TRUTH_DIR="${{ runner.workspace }}/artifacts/test_output_${TRUTH_BRANCH}_${{ matrix.python-version }}"
DIFF_DIR="${{ runner.workspace }}/diff_${{ matrix.python-version }}"

echo "Comparing $OUTPUT_DIR and $TRUTH_DIR"

# Ensure directories exist before running script
if [ -d "$OUTPUT_DIR" ] && [ -d "$TRUTH_DIR" ]; then
export METPLUS_DIFF_SKIP_KEYWORDS=".html,_rank.png"
python METplus/metplus/util/diff_util.py "$TRUTH_DIR" "$OUTPUT_DIR" --debug --save_diff
python METplus/metplus/util/diff_util.py "$TRUTH_DIR" "$OUTPUT_DIR" --debug --save_diff --diff_dir "$DIFF_DIR"
else
echo "One or both data directories are missing."
ls ${{ runner.workspace }}/artifacts
exit 1
fi

- name: Upload diff artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: diff_${{ matrix.python-version }}
path: ${{ runner.workspace }}/diff_${{ matrix.python-version }}
if-no-files-found: ignore
327 changes: 47 additions & 280 deletions metplotpy/plots/bar/bar.py

Large diffs are not rendered by default.

57 changes: 9 additions & 48 deletions metplotpy/plots/bar/bar_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@

import itertools

from ..config_plotly import Config
from .. import constants_plotly as constants
from .. import util_plotly as util
from ..config import Config
from .. import constants as constants

import metcalcpy.util.utils as utils

Expand Down Expand Up @@ -53,12 +52,12 @@ def __init__(self, parameters: dict) -> None:
# caption parameters
self.caption_size = int(constants.DEFAULT_CAPTION_FONTSIZE
* self.get_config_value('caption_size'))
self.caption_offset = self.parameters['caption_offset'] - 3.1
self.caption_offset = self.parameters['caption_offset'] * constants.DEFAULT_CAPTION_Y_OFFSET

##############################################
# title parameters
self.title_font_size = self.parameters['title_size'] * constants.DEFAULT_TITLE_FONT_SIZE
self.title_offset = self.parameters['title_offset'] * constants.DEFAULT_TITLE_OFFSET
self.title_offset = 1.0 + abs(self.parameters['title_offset']) * constants.DEFAULT_TITLE_OFFSET
self.y_title_font_size = self.parameters['ylab_size'] + constants.DEFAULT_TITLE_FONTSIZE

##############################################
Expand All @@ -76,7 +75,6 @@ def __init__(self, parameters: dict) -> None:
if self.x_tickangle in constants.XAXIS_ORIENTATION.keys():
self.x_tickangle = constants.XAXIS_ORIENTATION[self.x_tickangle]
self.x_tickfont_size = self.parameters['xtlab_size'] + constants.DEFAULT_TITLE_FONTSIZE
self.xaxis = util.apply_weight_style(self.xaxis, self.parameters['xlab_weight'])

##############################################
# x2-axis parameters
Expand Down Expand Up @@ -141,15 +139,13 @@ def _get_plot_disp(self) -> list:
def _get_fcst_vars(self, index):
"""
Retrieve a list of the inner keys (fcst_vars) to the fcst_var_val dictionary.

Args:
index: identifier used to differentiate between fcst_var_val_1 and
fcst_var_val_2 config settings
Returns:
a list containing all the fcst variables requested in the
fcst_var_val setting in the config file. This will be
used to subset the input data that corresponds to a particular series.

"""

fcst_var_val_dict = self.get_config_value('fcst_var_val_1')
Expand Down Expand Up @@ -183,38 +179,6 @@ def _get_plot_stat(self) -> str:
" Supported values are sum, mean, and median.")
return stat_to_plot

def _config_consistency_check(self) -> bool:
"""
Checks that the number of settings defined for plot_ci,
plot_disp, series_order, user_legend colors, and series_symbols
are consistent.

Args:

Returns:
True if the number of settings for each of the above
settings is consistent with the number of
series (as defined by the cross product of the model
and vx_mask defined in the series_val_1 setting)

"""
# Determine the number of series based on the number of
# permutations from the series_var setting in the
# config file

# Numbers of values for other settings for series
num_plot_disp = len(self.plot_disp)
num_series_ord = len(self.series_ordering)
num_colors = len(self.colors_list)
num_legends = len(self.user_legends)
status = False

if self.num_series == num_plot_disp == \
num_series_ord == num_colors \
== num_legends :
status = True
return status

def _get_user_legends(self, legend_label_type: str = '') -> list:
"""
Retrieve the text that is to be displayed in the legend at the bottom of the plot.
Expand Down Expand Up @@ -267,8 +231,8 @@ def get_series_y(self) -> list:
for x in reversed(list(all_fields_values_orig.keys())):
all_fields_values[x] = all_fields_values_orig.get(x)

if self._get_fcst_vars("1"):
all_fields_values['fcst_var'] = list(self._get_fcst_vars("1").keys())
if self.get_fcst_vars_keys(1):
all_fields_values['fcst_var'] = self.get_fcst_vars_keys(1)

all_fields_values['stat_name'] = self.get_config_value('list_stat_1')
return utils.create_permutations_mv(all_fields_values, 0)
Expand Down Expand Up @@ -301,12 +265,9 @@ def calculate_number_of_series(self) -> int:
"""
# Retrieve the lists from the series_val_1 dictionary
series_vals_list = self.series_vals_1.copy()
if isinstance(self.fcst_var_val_1, list) is True:
fcst_vals = self.fcst_var_val_1
elif isinstance(self.fcst_var_val_1, dict) is True:
fcst_vals = list(self.fcst_var_val_1.values())
fcst_vals_flat = [item for sublist in fcst_vals for item in sublist]
series_vals_list.append(fcst_vals_flat)
fcst_vals = list(self.fcst_var_val_1.values())
fcst_vals = [item for sublist in fcst_vals for item in sublist]
series_vals_list.append(fcst_vals)

# Utilize itertools' product() to create the cartesian product of all elements
# in the lists to produce all permutations of the series_val values and the
Expand Down
Loading
Loading