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

Feature 240 tcmpr #322

Merged
merged 10 commits into from
Feb 28, 2023
2 changes: 1 addition & 1 deletion metplotpy/plots/base_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ def remove_file(self):
image_name = self.get_config_value('plot_filename')

# remove the old file if it exist
if os.path.exists(image_name):
if image_name is not None and os.path.exists(image_name):
os.remove(image_name)

def show_in_browser(self):
Expand Down
2 changes: 1 addition & 1 deletion metplotpy/plots/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ def create_list_by_plot_val_ordering(self, setting_to_order: str) -> list:
return ordered_settings_list


def calculate_plot_dimension(self, config_value: int , output_units: str) -> int:
def calculate_plot_dimension(self, config_value: str , output_units: str) -> int:
'''
To calculate the width or height that defines the size of the plot.
Matplotlib defines these values in inches, Python plotly defines these
Expand Down
147 changes: 147 additions & 0 deletions metplotpy/plots/config/tcmpr_defaults.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
alpha: 0.05
colors:
- '#696969'
- '#0000FF'
- '#008000'
- '#000000'
- '#ff0000'
- '#800080'
- '#FFA500'
create_html: 'False'
derived_series_1: []
fixed_vars_vals_input:
BASIN:
BASIN_0:
- AL

grid_col: '#cccccc'
grid_lty: 3
grid_lwd: 1
grid_on: 'False'
grid_x: listX

indy_vals: []

indy_label: []

indy_var: 'LEAD'
legend_box: o
legend_inset:
x: 0.0
y: -0.25
legend_ncol: 3
legend_size: 0.8
line_type: None

list_stat_1: []

mar:
l: 0 #left margin
r: 0 #right margin
b: 105 #bottom margin
t: 120 #top margin
mgp:
- 1
- 1
- 0
plot_caption: ''
plot_disp: []

plot_height: 8.5
plot_res: 72
plot_stat: median
plot_type: png16m
plot_units: in
plot_width: 11.0
series_order: []
series_val_1: {}
series_ci: []
series_line_width:
- 1
- 1
- 1
series_line_style:
- '-'
- '-'
- '-'
series_symbols:
- 'circle-open'
- 'circle-open'
- 'circle-open'

series_symbols_size:
- 7
- 7
- 7


show_nstats: 'True'

tcst_dir:
tcst_files: []

title:
title_align: 0.5
title_offset: -2.0833
title_size: 1.4
title_weight: 2.0
user_legend: []
x2lab_align: 0.5
x2lab_offset: -0.5
x2lab_size: 0.8
x2lab_weight: 1
x2tlab_horiz: 0.5
x2tlab_orient: 1
x2tlab_perp: 1
x2tlab_size: 0.8
xaxis: 'Lead Time(h)'
xaxis_reverse: 'False'
xlab_align: 0.5
xlab_offset: 2
xlab_size: 1
xlab_weight: 1
xlim: []
xtlab_decim: 0
xtlab_horiz: 0.5
xtlab_orient: 1
xtlab_perp: -0.75
xtlab_size: 1

yaxis_1:
ylab_align: 0.5
ylab_offset: 15
ylab_size: 1
ylab_weight: 1
ylim: []
ytlab_horiz: 0.5
ytlab_orient: 1
ytlab_perp: 0.5
ytlab_size: 1

box_notch: True
box_outline: True
box_avg: True

caption_size: 0.8
caption_offset: 3
caption_weight: 1
caption_align: 0
caption_col: '#333333'
n_min: 11
plot_list: [] # boxplot, point, mean, median, relperf, rank, scatter ,skill_mn, skill_md
rp_diff:
- '>=100'
hfip_bsln: no
footnote_flag: 'False'
event_equal: 'False'
skill_ref: []
demo_yr: NA #not used in Rscript. not sure if we need it
scatter_x: []
scatter_y: []
plot_dir: './'
subtitle: ''
prefix:
baseline_file: ./hfip_baseline.dat
column_info_file: ./plot_tcmpr_hdr.dat


4 changes: 2 additions & 2 deletions metplotpy/plots/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@


AVAILABLE_MARKERS_LIST = ["o", "^", "s", "d", "H", ".", "h"]
AVAILABLE_PLOTLY_MARKERS_LIST = ["open-circle", "circle",
AVAILABLE_PLOTLY_MARKERS_LIST = ["circle-open", "circle",
"square", "diamond",
"hexagon", "triangle-up"]
"hexagon", "triangle-up", "asterisk-open"]

PCH_TO_MATPLOTLIB_MARKER = {'20': '.', '19': 'o', '17': '^', '1': 'H',
'18': 'd', '15': 's', 'small circle': '.',
Expand Down
3 changes: 2 additions & 1 deletion metplotpy/plots/line/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ def _add_xaxis(self) -> None:
},
title_standoff=abs(self.config_obj.parameters['xlab_offset']),
tickangle=self.config_obj.x_tickangle,
tickfont={'size': self.config_obj.x_tickfont_size}
tickfont={'size': self.config_obj.x_tickfont_size},
tickformat='d'
)

def _add_yaxis(self) -> None:
Expand Down
Empty file.
Empty file.
89 changes: 89 additions & 0 deletions metplotpy/plots/tcmpr_plots/box/tcmpr_box.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import os

import plotly.graph_objects as go

from plots.tcmpr_plots.box.tcmpr_box_point import TcmprBoxPoint
from plots.tcmpr_plots.tcmpr_series import TcmprSeries


class TcmprBox(TcmprBoxPoint):
def __init__(self, config_obj, column_info, col, case_data, input_df, baseline_data):
super().__init__(config_obj, column_info, col, case_data, input_df, baseline_data)

print("--------------------------------------------------------")
print(f"Plotting BOXPLOT time series by {self.config_obj.series_val_names[0]}")
self._adjust_titles()
self.series_list = self._create_series(self.input_df)
self.case_data = None
self.cur_baseline = baseline_data['cur_baseline']
self.cur_baseline_data = baseline_data['cur_baseline_data']
self._init_hfip_baseline_for_plot()

if self.config_obj.prefix is None or len(self.config_obj.prefix) == 0:
self.plot_filename = f"{self.config_obj.plot_dir}{os.path.sep}{self.config_obj.list_stat_1[0]}_boxplot.png"
else:
self.plot_filename = f"{self.config_obj.plot_dir}{os.path.sep}{self.config_obj.prefix}.png"

# remove the old file if it exist
if os.path.exists(self.plot_filename):
os.remove(self.plot_filename)
self._create_figure()

def _adjust_titles(self):
if self.yaxis_1 is None or len(self.yaxis_1) == 0:
self.yaxis_1 = self.config_obj.list_stat_1[0] + '(' + self.col['units'] + ')'

if self.title is None or len(self.title) == 0:
self.title = 'Boxplots of ' + self.col['desc'] + ' by ' \
+ self.column_info[self.column_info['COLUMN'] == self.config_obj.series_val_names[0]][
"DESCRIPTION"].tolist()[0]

def _draw_series(self, series: TcmprSeries) -> None:
"""
Draws the boxes on the plot

:param series: Line series object with data and parameters
"""

# defaults markers and colors for the regular box plot
line_color = dict(color='rgb(0,0,0)')
marker_color = series.color
marker_line_color = series.color

if len([x for x in series.series_data['PLOT'].tolist() if x is not None]) < self.config_obj.n_min:
line_color = dict(color='rgba(0,0,0,0)')
fillcolor = 'rgba(0,0,0,0)'
marker_symbol = 'circle'
else:
if series.color == 'rgb(0,0,0)' or series.color == 'black' or series.color == '#000000':
fillcolor = '#ffffff'
else:
fillcolor = series.color
marker_symbol = 'circle-open'

# create a trace
self.figure.add_trace(
go.Box(x=series.series_data['LEAD_HR'],
y=series.series_data['PLOT'],
mean=series.series_points['mean'],
notched=self.config_obj.box_notch,
line=line_color,
fillcolor=fillcolor,
name=series.user_legends,
showlegend=True,
# quartilemethod='linear', #"exclusive", "inclusive", or "linear"
boxmean=self.config_obj.box_avg,
boxpoints='outliers', # outliers, all, False
pointpos=0,
marker=dict(size=4,
color=marker_color,
line=dict(
width=1,
color=marker_line_color
),
symbol=marker_symbol,
),
jitter=0
),
secondary_y=series.y_axis != 1
)
75 changes: 75 additions & 0 deletions metplotpy/plots/tcmpr_plots/box/tcmpr_box_point.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from plots.tcmpr_plots.tcmpr import Tcmpr
from plots.tcmpr_plots.tcmpr_series import TcmprSeries


class TcmprBoxPoint(Tcmpr):
def __init__(self, config_obj, column_info, col, case_data, input_df, baseline_data):
super().__init__(config_obj, column_info, col, case_data, input_df)

def _init_hfip_baseline_for_plot(self):
if 'Water Only' in self.config_obj.title or self.cur_baseline == 'no':
print("Plot HFIP Baseline:" + self.cur_baseline)
else:
self.cur_baseline_data = self.cur_baseline_data[(self.cur_baseline_data['TYPE'] == 'CONS')]
print('Plot HFIP Baseline:' + self.cur_baseline.replace('Error ', ''))

def _draw_series(self, series: TcmprSeries) -> None:
pass

def _create_figure(self):
""" Create a box plot from default and custom parameters"""

self.figure = self._create_layout()
self._add_xaxis()
self._add_yaxis()
self._add_legend()

# placeholder for the min and max values for y-axis
yaxis_min = None
yaxis_max = None

if self.config_obj.xaxis_reverse is True:
self.series_list.reverse()

# add x ticks for line plots
self.figure.update_layout(
xaxis={
'tickmode': 'array',
'tickvals': self.config_obj.indy_vals,
'ticktext': self.config_obj.indy_label
}
)

for series in self.series_list:
# Don't generate the plot for this series if
# it isn't requested (as set in the config file)
if series.plot_disp:
# collect min-max if we need to sync axis
yaxis_min, yaxis_max = self.find_min_max(series, yaxis_min, yaxis_max)
self._draw_series(series)

print(f'Range of {self.config_obj.list_stat_1[0]}: {yaxis_min}, {yaxis_max}')
self._add_hfip_baseline()

self.figure.update_layout(shapes=[dict(
type='line',
yref='y', y0=0, y1=0,
xref='paper', x0=0, x1=0.95,
line={'color': '#727273',
'dash': 'dot',
'width': 1},
)])

self.figure.update_layout(boxmode='group')

# add custom lines
if len(self.series_list) > 0:
self._add_lines(
self.config_obj,
sorted(self.series_list[0].series_data[self.config_obj.indy_var].unique())
)
# apply y axis limits
self._yaxis_limits()

# add x2 axis
self._add_x2axis(self.config_obj.indy_vals)
Loading