To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit 9af1d38d authored by holukas's avatar holukas
Browse files

updated MDS gap-filling

parent 102551ac
......@@ -8,9 +8,6 @@
<orderEntry type="jdk" jdkName="Python 3.6 (AMP06)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="myDocStringFormat" value="NumPy" />
</component>
<component name="TestRunnerService">
<option name="projectConfiguration" value="pytest" />
<option name="PROJECT_TEST_RUNNER" value="pytest" />
......
This diff is collapsed.
......@@ -75,7 +75,7 @@
33. when importing data from file, renaming columns possible in GUI, and if name already exists then ask if it should be merged with existing
34. when importing data and data column already exists, define both should be merged or one prioritized over the other
35. output some kind of stats overview page for all vars
36. CHECK: whether other methods also need shifted timestamp column, e.g. I think in u* filtering, or resampling to e.g. daily average
36. CHECK: whether other methods also need shifted timestamp column, e.g. I think in u* filtering, or resampling to e.g. daily average (for ustar checked in 0.9.0)
37. **Modifications:** convert *complete* df to e.g. daily average, or also something like running median lines etc…
38. hexbins per year etc option
39. Waffle chart: https://github.com/gyli/PyWaffle
......
......@@ -63,7 +63,7 @@ class Ui_MainWindow(object):
f"{info['version']}")
MainWindow.setWindowIcon(QIcon(self.ctx.icon_amp))
# MainWindow.setWindowIcon(QIcon('gui/Icons/python_icon.png'))
MainWindow.resize(1500, 1000)
MainWindow.resize(1920, 1080)
MainWindow.setContentsMargins(0, 0, 0, 0)
# Init CentralWidget (level 1)
......@@ -162,6 +162,7 @@ class Ui_MainWindow(object):
lyt_FocusAreaGrid = qw.QGridLayout()
# lyt_FocusAreaVert = qw.QVBoxLayout()
lyt_FocusAreaGrid.setContentsMargins(0, 0, 0, 0)
lyt_FocusAreaGrid.setSpacing(5)
# Init StretchBox, used where needed
# grd_Stretch = GUI_BuildingBlocks.StretchBox().get_frame()
......@@ -170,9 +171,22 @@ class Ui_MainWindow(object):
# HEADER ///////////////////////////////////////////////////////////
# ==================================================================
# # todo testing font size
# font = QFont()
# font.setFamily("Arial")
# font.setPointSize(9999)
# font.setBold(True)
self.lbl_FocusVariableName = qw.QLabel('*Please Select Variable*')
self.lbl_FocusVariableName.setProperty('labelClass', 'lbl_Header1')
# self.texteditor1 = QtGui.QLineEdit(self)
# font = self.lbl_FocusVariableName.font() # lineedit current font
# font.setPointSize(32) # change it's size
# self.lbl_FocusVariableName.setFont(font) # set font
# self.lbl_FocusVariableName.setFont(font)
# ==================================================================
# PLOTS & STATS ////////////////////////////////////////////////////
# ==================================================================
......@@ -233,6 +247,7 @@ class Ui_MainWindow(object):
frm_Categories.setProperty('labelClass', 'frm_Categories')
self.grd_categories = qw.QGridLayout()
self.grd_categories.setContentsMargins(0, 0, 0, 0)
self.grd_categories.setSpacing(5)
frm_Categories.setLayout(self.grd_categories)
# Init options stack
......@@ -314,23 +329,10 @@ class Ui_MainWindow(object):
def add_modbox_Plots(self):
# CATEGORY 0: PLOTS (ModBox)
self.btn_pl_cat_Plots_showStack, \
self.btn_pl_opt_Heatmap, \
self.btn_pl_ref_Heatmap_showInNewTab, \
self.pl_ref_Heatmap_stackTab, \
self.btn_pl_opt_Scatter, \
self.pl_ref_Scatter_stackTab, \
self.btn_pl_ref_Scatter_showInNewTab, \
self.pl_ref_FXN_ThresholdPlots_stackTab, \
self.btn_pl_opt_FXN_ThresholdPlots, \
self.btn_pl_ref_FXN_ThresholdPlots_showInNewTab, \
self.pl_ref_Hexbins_stackTab, \
self.btn_pl_opt_Hexbins, \
self.btn_pl_ref_Hexbins_showInNewTab = \
modbox_pl.AddControls(grd_Categories=self.grd_categories,
self.modbox_plots = modbox_pl.AddControls(grd_Categories=self.grd_categories,
stk_Options=self.stk_category_options,
stk_Refinements=self.stk_option_refinements,
ctx=self.ctx).get_handles()
ctx=self.ctx)
def add_modbox_QualityControl(self):
self.qc_ref_AmpQcFlags_stackTab, \
......
......@@ -24,6 +24,7 @@ def grd_Button(lyt, txt, css_id, row, col, rowspan, colspan):
lyt.addWidget(button, row, col, rowspan, colspan)
return button
def grd_ButtonIcon(lyt, txt, css_id, row, col, rowspan, colspan, icon):
button = qw.QPushButton(text=txt)
button.setProperty('labelClass', css_id)
......@@ -105,8 +106,12 @@ def grd_LabelLineditPair(txt, css_ids, layout, row, col, orientation):
layout.addWidget(lbl_txt, row, col, 1, 1)
layout.addWidget(lne_val, row + 1, col, 1, 1)
layout.setColumnStretch(0, 0)
layout.setColumnStretch(1, 1)
return lne_val
def grd_LabelDateEditPair(layout, row, col, css_ids, txt):
lbl_txt = qw.QLabel(text=txt)
dte_date = qw.QDateEdit()
......@@ -121,6 +126,7 @@ def grd_LabelDateEditPair(layout, row, col, css_ids, txt):
# date_edit.calendarWidget().installEventFilter()
return dte_date
def grd_LabelLineeditDropdownTriplet(txt, css_ids, layout, row, col, orientation):
# Adds two labels to a grid lyt_CategoryOptions: one for the label text, one for the value.
# Returns the id for the value label so it can later be updated with real values.
......@@ -146,6 +152,7 @@ def grd_LabelDropdownPair(txt, css_ids, layout, row, col, orientation):
# Returns the id for the value label so it can later be updated with real values.
lbl_txt = qw.QLabel(text=txt)
drp_options = qw.QComboBox()
drp_options.setMaxVisibleItems(30)
lbl_txt.setProperty('labelClass', css_ids[0])
drp_options.setProperty('labelClass', css_ids[1])
......@@ -197,6 +204,7 @@ class ComboBox_dropEnabled(qw.QComboBox):
self.model_mime_type = 'application/x-qabstractitemmodeldatalist' ## format from variable list
super(ComboBox_dropEnabled, self).__init__()
self.setAcceptDrops(True)
self.setMaxVisibleItems(30)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat(self.model_mime_type) or event.mimeData().hasFormat('text/plain'):
......
import ast
import datetime as dt
import fnmatch
import zipfile as zf
from pathlib import Path
......@@ -22,12 +23,12 @@ from inout.FileTypes import IfDews_1T
from inout.FileTypes import NABEL_1T
from inout.FileTypes import TOA5_10T
from inout.FileTypes import TOA5_1T
from inout.GlobalVars import *
from inout.TimestampTypes import C1_FullDateTimeDayFirstNoSec
from inout.TimestampTypes import C1_FullDateTimeNanosec
from inout.TimestampTypes import C1_FullDateTimeNoSec
from inout.TimestampTypes import C1_FullDateTimeOneNumber
from inout.TimestampTypes import C1_FullDateTimeWithSec
from inout.TimestampTypes import C1_FullDateNoTime
from inout.TimestampTypes import C2_DateAndTime
from inout.TimestampTypes import NoTimestamp
......@@ -648,12 +649,15 @@ def sort_multiindex_columns_names(df, priority_vars):
# Put priority vars first
for ix, col in enumerate(cols_list):
if col[0] in priority_vars:
cols_list.insert(0, cols_list.pop(ix)) # removes from old location ix, puts to top of list
# Custom vars are marked w/ point at beginning
for ix, col in enumerate(cols_list):
if col[0].startswith('.'):
elif col[0].startswith('.'):
cols_list.insert(0, cols_list.pop(ix))
elif any(fnmatch.fnmatch(col[0], gf_id) for gf_id in GAPFILLED_GENERAL_SCALARS):
cols_list.insert(0, cols_list.pop(ix))
df = df[cols_list] # assign new (sorted) column order
......@@ -931,14 +935,30 @@ def resample_df(df, freq_str, agg_method, min_vals, orig_freq):
return agg_df
def df_between_two_dates(df, start_date, end_date):
def df_between_two_dates(df, start_date, end_date, dropna, dropna_col):
""" Get data for the time window, greater than the start date and smaller than the end date.
:param df: DataFrame
:param start_date: datetime
:param end_date: datetime
:param dropna: bool
:param dropna_col: Column name in df that is checked for NaNs.
:return: Data between start_date and end_date.
:rtype: DataFrame
"""
mask = (df.index >= start_date) & (df.index <= end_date)
snippet_df = df.loc[mask]
if dropna:
# Remove rows in df where dropna_col is NaN.
filter_nan = snippet_df[dropna_col].isnull() # True if NaN
snippet_df = snippet_df.loc[~filter_nan] # Keep False (=values, i.e. not NaN)
# snippet_df = snippet_df.dropna()
return snippet_df
def insert_datetimerange(df, win_days, win_hours):
# insert date ranges, varying colnames depending on settings
"""Insert datetime range that describes start and end of chosen day window."""
win_start_col = ('start_dt_{}d-{}h'.format(win_days, win_hours), '[datetime]')
win_end_col = ('end_dt_{}d-{}h'.format(win_days, win_hours), '[datetime]')
df[win_start_col] = df.index - pd.Timedelta(days=win_days) - pd.Timedelta(hours=win_hours)
......@@ -947,7 +967,7 @@ def insert_datetimerange(df, win_days, win_hours):
def insert_timerange(df, win_hours):
# insert date ranges, varying colnames depending on settings
"""Insert time range that describes start and end of chosen hour window."""
win_start_time_col = ('start_time_{}h'.format(win_hours), '[time]')
win_end_time_col = ('end_time_{}h'.format(win_hours), '[time]')
df[win_start_time_col] = df.index - pd.Timedelta(hours=win_hours)
......@@ -972,7 +992,6 @@ def find_nans_in_df_col(df, col):
temp = pd.isnull(df[col]).to_numpy().nonzero()
gaps_df = df.ix[temp] # contains only NEE NaNs, but the index is important to locate missing NEE values
gap_count = len(gaps_df[col])
return gaps_df, gap_count
......
AIR_TEMPERATURE = ['*TA_*', '*air_temperature*']
AIR_TEMPERATURE_METEO = ['*TA_*']
AIR_TEMPERATURE_EDDYPRO = ['*air_temperature*']
AIR_TEMPERATURE = AIR_TEMPERATURE_METEO + AIR_TEMPERATURE_EDDYPRO
FLUXES_EDDYPRO = ['co2_flux', 'h2o_flux', 'LE', 'H', 'ET', 'n2o_flux', 'ch4_flux']
FLUXES_FLUXNET = ['NEE*', 'GPP*', 'RECO*']
......@@ -13,6 +15,8 @@ FLUXES_GENERAL_N2O = ['*n2o_flux*']
FLUX_SCALARS_CO2_HIRES = ['co2_ppb*', 'CO2_ppm*', 'CO2_mmol_m-3*']
GAPFILLED_GENERAL_SCALARS = ['*-f*']
MONIN_OBUKHOV_STABILITY = ['(z-d)/L']
# ==============================================================================================
......
......@@ -106,8 +106,8 @@ class Amp(QtWidgets.QMainWindow, Ui_MainWindow, GUI_BuildingBlocks.SettingsWindo
# ==================================================================
# Load example file when script starts
# self.initial_data, self.settings_dict = example_files.load(file='Amp_30T')
# self.initial_data, self.settings_dict = example_files.load(file='AmpCSV_30T', ctx=self.ctx)
self.initial_data, self.settings_dict = example_files.load(file='EddyProFullOutput_30T', ctx=self.ctx)
self.initial_data, self.settings_dict = example_files.load(file='AmpCSV_30T', ctx=self.ctx)
# self.initial_data, self.settings_dict = example_files.load(file='EddyProFullOutput_30T', ctx=self.ctx)
# self.initial_data, self.settings_dict = example_files.load(file='FluxnetFullSet_30T', ctx=self.ctx)
# self.initial_data, self.settings_dict = example_files.load(file='HiRes_20Hz', ctx=self.ctx)
# self.initial_data, self.settings_dict = example_files.load(file='IfDews_1T', ctx=self.ctx)
......@@ -158,7 +158,7 @@ class Amp(QtWidgets.QMainWindow, Ui_MainWindow, GUI_BuildingBlocks.SettingsWindo
if self.load_initial_data:
self.select_source(action='load_initial_data')
# self.plot_focus(fig=-9999, plot_type='OVERVIEW')
# self.make_tab(make_tab='MDS')
self.make_tab(make_tab='MDS')
# self.make_tab(make_tab='USTAR_DETECTION') # e.g., shortcut to ustar detection
# self.make_tab(make_tab='AGGREGATOR')
# self.make_tab(make_tab='SCATTER')
......@@ -284,7 +284,8 @@ class Amp(QtWidgets.QMainWindow, Ui_MainWindow, GUI_BuildingBlocks.SettingsWindo
except ValueError: ## which means no overlapping column names
self.data_df = self.data_df.join(incoming_data_df, how='outer')
self.data_df = data_fn.sort_multiindex_columns_names(df=self.data_df, priority_vars=FLUXES)
self.data_df = data_fn.sort_multiindex_columns_names(df=self.data_df,
priority_vars=FLUXES + GAPFILLED_GENERAL_SCALARS)
self.update_gui_lists()
def get_source_files_list(self, action):
......@@ -392,9 +393,9 @@ class Amp(QtWidgets.QMainWindow, Ui_MainWindow, GUI_BuildingBlocks.SettingsWindo
'Error': e,
'Recommendation': 'Check if File Settings are correct for this file.'}, highlight=False)
print("\n(!)SKIPPED FILES")
print(skipped_files_list)
print("\n")
# print("\n(!)SKIPPED FILES")
# print(skipped_files_list)
# print("\n")
return all_data_df
......@@ -506,7 +507,7 @@ class Amp(QtWidgets.QMainWindow, Ui_MainWindow, GUI_BuildingBlocks.SettingsWindo
# # OUTLIER DETECTION: Double-Differenced Time Series
# if colname_tuple[0].endswith('daytime'):
# self.drp_od_ref_DoubleDiff_defineNighttimeDataAs.addItem(colname_pretty_string)
# self.drp_od_ref_DoubleDiff_defineNighttimeDataAs.addItem(col_list_pretty)
# QUALITY CONTROL
# --------------------------------------
......@@ -808,7 +809,7 @@ class Amp(QtWidgets.QMainWindow, Ui_MainWindow, GUI_BuildingBlocks.SettingsWindo
self.make_tab_ustar()
elif make_tab == 'MDS':
self.make_tab_mds()
self.mds_make_tab()
elif make_tab == 'AGGREGATOR':
self.make_tab_aggregator()
......@@ -1017,68 +1018,48 @@ class Amp(QtWidgets.QMainWindow, Ui_MainWindow, GUI_BuildingBlocks.SettingsWindo
break
return tab_exists, nt
def make_tab_mds(self):
def mds_make_tab(self):
"""Make new tab and store current data_df in instance."""
tab_exists, tab_number = self.check_if_tab_exists(tab_name='MDS')
# In case the tab already exists, activate the existing tab, otherwise make new tab
if tab_exists:
self.TabWidget.setCurrentIndex(tab_number)
# pass
else:
# Create tab
self.drp_gf_MDS_flux, self.drp_gf_MDS_swin, self.drp_gf_MDS_ta, self.drp_gf_MDS_vpd, \
self.lne_gf_MDS_swin_sim, self.lne_gf_MDS_ta_sim, self.lne_gf_MDS_vpd_sim, \
self.drp_gf_MDS_templateReference, self.btn_gf_MDS_start_qual_A, self.btn_gf_MDS_start_qual_B, \
self.btn_gf_MDS_start_qual_C, self.lne_gf_MDS_time_win_days, \
self.lne_gf_MDS_time_win_hours, self.fig_gf_MDS, self.axes_dict_gf_MDS, \
self.gf_MDS_progress_bar, self.btn_gf_MDS_init = \
gf_MDS.MakeNewTab(TabWidget=self.TabWidget,
colname_pretty_string=self.selected_file_colnames_pretty_strings_list,
data_df=self.data_df).get_handles()
self.MDS_Tab = gf_MDS.MakeNewTab(TabWidget=self.TabWidget,
col_dict_tuples=self.selected_file_colnames_tuples_dict,
col_list_pretty=self.selected_file_colnames_pretty_strings_list,
data_df=self.data_df)
self.btn_gf_MDS_init.clicked.connect(self.mds_init_data)
self.MDS_Tab.btn_init.clicked.connect(self.mds_init_data)
def mds_init_data(self):
# Create object
self.obj_mds = gf_MDS.StartMDSgapfilling(col_dict_tuples=self.selected_file_colnames_tuples_dict,
data_df=self.data_df,
fig=self.fig_gf_MDS,
flux_data_col=self.drp_gf_MDS_flux.currentText(),
ta_data_col=self.drp_gf_MDS_ta.currentText(),
swin_data_col=self.drp_gf_MDS_swin.currentText(),
vpd_data_col=self.drp_gf_MDS_vpd.currentText(),
col_list_pretty=self.selected_file_colnames_pretty_strings_list,
axes_dict=self.axes_dict_gf_MDS,
button_qual_A=self.btn_gf_MDS_start_qual_A,
button_qual_B=self.btn_gf_MDS_start_qual_B,
button_qual_C=self.btn_gf_MDS_start_qual_C,
swin_sim_lim=float(self.lne_gf_MDS_swin_sim.text()),
ta_sim_lim=float(self.lne_gf_MDS_ta_sim.text()),
vpd_sim_lim=float(self.lne_gf_MDS_vpd_sim.text()),
time_win_days=int(self.lne_gf_MDS_time_win_days.text()),
time_win_hours=int(self.lne_gf_MDS_time_win_hours.text()),
progress_bar=self.gf_MDS_progress_bar)
"""Prepare data for MDS gap-filling."""
self.obj_mds = gf_MDS.RunMDS(mds_tab=self.MDS_Tab)
# Start gap-filling when button is pressed
self.btn_gf_MDS_start_qual_A.clicked.connect(lambda: self.mds_get_results(which='quality_A'))
self.btn_gf_MDS_start_qual_B.clicked.connect(lambda: self.mds_get_results(which='quality_B'))
self.btn_gf_MDS_start_qual_C.clicked.connect(lambda: self.mds_get_results(which='quality_C'))
self.obj_mds.btn_qual_A.clicked.connect(lambda: self.mds_get_results(which='quality_A'))
self.obj_mds.btn_qual_B.clicked.connect(lambda: self.mds_get_results(which='quality_B'))
self.obj_mds.btn_qual_C.clicked.connect(lambda: self.mds_get_results(which='quality_C'))
self.obj_mds.btn_calc_unc.clicked.connect(lambda: self.mds_get_results(which='uncertainty'))
self.update_gui_lists()
def mds_get_results(self, which):
""" Perform gap-filling and put gap-filled values into the main df
"""
"""Perform gap-filling and put gap-filled values into the main df."""
if which == 'quality_A':
self.obj_mds.gapfilling_quality_A()
elif which == 'quality_B':
self.obj_mds.gapfilling_quality_B()
elif which == 'quality_C':
self.obj_mds.gapfilling_quality_C()
elif which == 'uncertainty':
self.obj_mds.calculate_uncertainty()
self.data_df = self.obj_mds.get_filled()
self.data_df = data_fn.sort_multiindex_columns_names(df=self.data_df, priority_vars=FLUXES)
self.data_df = self.obj_mds.get_filled(add_to_df=self.data_df) # Add results to main data_df
self.data_df = data_fn.sort_multiindex_columns_names(df=self.data_df,
priority_vars=FLUXES + GAPFILLED_GENERAL_SCALARS)
self.update_gui_lists()
def make_tab_ustar(self):
......@@ -1548,7 +1529,9 @@ class AppContext(ApplicationContext): # 1. Subclass ApplicationContext
# Example files
@cached_property
def file_AmpCSV_30T(self):
return self.get_resource('example_files/AmpCSV_30T.csv') # Returns absolute path
return self.get_resource(
'example_files/CH-OE2_Dataset_AMP-20191025-145003_Original-30T.csv') # Returns absolute path
# return self.get_resource('example_files/AmpCSV_30T.csv') # Returns absolute path
@cached_property
def file_EddyProFullOutput_30T(self):
......
......@@ -584,7 +584,7 @@ class MakeUstarAnalysis:
bts_results_sorted = bts_results
overall_ustar_threshold = bts_results_sorted[0]
self.data_df=self.make_insert_qc_flag(overall_ustar_threshold=overall_ustar_threshold, df=self.data_df)
self.data_df = self.make_insert_qc_flag(overall_ustar_threshold=overall_ustar_threshold, df=self.data_df)
GUI_Elements.btn_txt_live_update(btn=self.button, txt=self.button_orig_text, perc=-9999)
......@@ -1055,7 +1055,7 @@ class MakeUstarAnalysis:
ax.plot_date(x=class_group.index, y=class_group[data_col], c=class_colors_dict[class_key], alpha=0.5,
markeredgecolor='none', marker='o')
Format(ax=ax, label_color='#eab839', xlabel='-', ylabel='-', ylabel_units='-', fontsize='large')
Format(ax=ax, txt_xlabel='-', txt_ylabel='-', txt_ylabel_units='-', label_color='#eab839', fontsize='large')
ax.text(0.05, 0.95, "{} per {}".format(data_col[0], class_id_col[0]),
horizontalalignment='left', verticalalignment='top', transform=ax.transAxes,
......
......@@ -62,17 +62,18 @@ class Call:
def __init__(self, data_df, drp_ind_var_col, fig, ax, focus_df, focus_col, col_dict_tuples):
self.data_df = data_df
self.data_df = data_df.copy()
self.fig = fig # needed for redraw
self.ax = ax # adds to existing axis
self.focus_df = focus_df.copy()
self.focus_col = focus_col
self.focus_df = self.focus_df[[self.focus_col]] # Basically resets focus_df, deletes prev aux columns
self.drp_ind_var_col = drp_ind_var_col
self.col_dict_tuples = col_dict_tuples
# Define MultiIndex column names
focus_name = self.focus_col[0]
self.focus_col_gf = (f"{focus_name}_f", '[marker]')
self.focus_col_gf = (f"{focus_name}_f", f"{self.focus_col[1]}")
self.predicted_vals_col = (f"{focus_name}_predicted", '[aux]')
self.gap_values_col = (f"{focus_name}_gap_vals", '[aux]')
......
This diff is collapsed.
......@@ -87,7 +87,6 @@ class Call:
self.method = method.currentText()
self.get_data()
self.gapfilling_running_simple()
def make_required_cols(self):
......@@ -97,11 +96,7 @@ class Call:
# self.focus_col_gf = ('gf_RunningSimple', 'marker')
self.focus_col_gf = (self.focus_col[0] + '_f', self.focus_col[1])
def get_data(self):
pass
def gapfilling_running_simple(self):
self.filter_suffix = '_GF-SRM'
# Detect missing values in measured
filter_nan = self.focus_df[self.focus_col].isnull()
......
......@@ -3,7 +3,7 @@ from gui import GUI_Elements
def remove_prev_lines(ax):
# Every time the slider multiplier is changed to a new value,
# the marker that show the outlier values are drawn.
# the marker that shows the outlier values are drawn.
# In case there is already a marker in the plot, it needs to be
# removed first, then the new markers are drawn.
# Since the main plot of the time series is line 0, the marker
......@@ -18,7 +18,6 @@ def remove_prev_lines(ax):
for l in range(num_lines):
try:
ax.lines[1].remove()
except:
pass
......@@ -26,7 +25,7 @@ def remove_prev_lines(ax):
ax.collections = []
# Remove all texts in axis
ax.texts = [] ## this is so much simpler I cant believe it
ax.texts = [] ## this is so much simpler I cannot believe it
# num_lines = len(ax.lines)
# for l in range(num_lines):
......
......@@ -37,23 +37,12 @@ class AddControlsToMain():
self.opt_frame = opt_frame
self.opt_layout = opt_layout
self.ref_stack = ref_stack
self.add_option()
self.add_refinements()
# self.get_handles()
def get_handles(self):
return self.btn_pl_opt_FXN_ThresholdPlots, \
self.btn_pl_ref_FXN_ThresholdPlots_showInNewTab
# self.drp_pl_ref_FXN_ThresholdPlots_flux, \
# self.drp_pl_ref_FXN_ThresholdPlots_UstarMethod, \
# self.drp_pl_ref_FXN_ThresholdPlots_partitioningMethod, \
# self.drp_pl_ref_FXN_ThresholdPlots_markGapfilledVals, \
def add_option(self):
# Option Button: [2] Heatmap
self.btn_pl_opt_FXN_ThresholdPlots = GUI_Elements.grd_Button(lyt=self.opt_layout,
self.opt_btn = GUI_Elements.grd_Button(lyt=self.opt_layout,
txt='Threshold Plots', css_id='',
row=4, col=0, rowspan=1, colspan=1)
......@@ -65,7 +54,7 @@ class AddControlsToMain():
ModBoxes_shared.add_header(layout=ref_layout, header='PL: Threshold Plots')
self.btn_pl_ref_FXN_ThresholdPlots_showInNewTab = \
self.ref_btn_showInNewTab = \
GUI_Elements.grd_Button(lyt=ref_layout,
txt='+ Show in New Tab', css_id='',
row=1, col=0, rowspan=1, colspan=2)
......@@ -124,8 +113,7 @@ class MakeNewTab:
gs.update(wspace=0.3, hspace=0.3, left=0.03, right=0.97, top=0.97, bottom=0.03)
# 3 axes w/ different percentile limits
tabAx = tabFigure.add_subplot(gs[0, 0])
Format(ax=tabAx, label_color='#eab839', xlabel='-',
ylabel='-', ylabel_units='-', fontsize='large')
Format(ax=tabAx, txt_xlabel='-', txt_ylabel='-', txt_ylabel_units='-', label_color='#eab839', fontsize='large')
# Navigation (right)
tabToolbar = NavigationToolbar(tabCanvas, parent=self.TabWidget)
......@@ -353,10 +341,9 @@ class MakeFXNThresholdPlots:
text.set_color("#999c9f")
# Format
Format(ax=ax, label_color='#eab839', xlabel='DATE',
ylabel='{} with {} and {}'.format(
self.drp_flux, self.drp_ustar_method, self.drp_partitioning_method),
ylabel_units='DATE', fontsize='large')
Format(ax=ax, txt_xlabel='DATE', txt_ylabel='{} with {} and {}'.format(
self.drp_flux, self.drp_ustar_method, self.drp_partitioning_method), txt_ylabel_units='DATE',
label_color='#eab839', fontsize='large')
# Title
if self.drp_flux == 'NEE':
......
......@@ -10,7 +10,7 @@ from modboxes import ModBoxes_shared
from modboxes.Plots import Plots_shared
class AddControls():
class AddControlsToMain():
"""
Creates the gui control elements and their handles for usage.
......@@ -21,18 +21,12 @@ class AddControls():
self.opt_frame = opt_frame
self.opt_layout = opt_layout
self.ref_stack = ref_stack
self.add_option()
self.add_refinements()
# self.get_handles()
def get_handles(self):
return self.btn_pl_opt_Heatmap, \
self.btn_pl_ref_Heatmap_showInNewPlot
def add_option(self):
# Option Button: [2] Heatmap
self.btn_pl_opt_Heatmap = GUI_Elements.grd_Button(lyt=self.opt_layout,
self.opt_btn = GUI_Elements.grd_Button(lyt=self.opt_layout,
txt='Heatmap', css_id='',
row=2, col=0, rowspan=1, colspan=1)
......@@ -44,15 +38,13 @@ class AddControls():
ModBoxes_shared.add_header(layout=ref_layout, header='PL: Heatmap')
self.btn_pl_ref_Heatmap_showInNewPlot = \
self.ref_btn_showInNewTab = \
GUI_Elements.grd_Button(lyt=ref_layout,
txt='+ Show in New Tab', css_id='',
row=1, col=0, rowspan=1, colspan=2)
ref_layout.setRowStretch(2, 1)
return self
class Call: