diff --git a/mlair/plotting/postprocessing_plotting.py b/mlair/plotting/postprocessing_plotting.py index b23807ae30f52f19581b188d19213fdc81c9258e..5bd4ab1bdc127d18dcb096508d9be0ff4853b7b6 100644 --- a/mlair/plotting/postprocessing_plotting.py +++ b/mlair/plotting/postprocessing_plotting.py @@ -1112,7 +1112,7 @@ class PlotSampleUncertaintyFromBootstrap(AbstractPlotClass): # pragma: no cover self.prepare_data(data) # create all combinations to plot (h/v, utest/notest, single/multi) - variants = list(itertools.product(*[["v", "h"], [True, False], ["single", "multi"]])) + variants = list(itertools.product(*[["v", "h"], [True, False], ["single", "multi", "panel"]])) # plot raw metric (mse) for orientation, utest, agg_type in variants: @@ -1157,7 +1157,9 @@ class PlotSampleUncertaintyFromBootstrap(AbstractPlotClass): # pragma: no cover if apply_u_test is True and agg_type == "multi": return # not implemented data_table = self._data_table - if self.ahead_dim not in data_table.index.names and agg_type == "multi": + if self.ahead_dim not in data_table.index.names and agg_type in ["multi", "panel"]: + return # nothing to do + if apply_u_test is True and agg_type == "panel": return # nothing to do n_boots = self._n_boots size = len(np.unique(data_table.columns)) @@ -1177,7 +1179,7 @@ class PlotSampleUncertaintyFromBootstrap(AbstractPlotClass): # pragma: no cover showmeans=True, meanprops={"markersize": 6, "markeredgecolor": "k"}, flierprops={"marker": "o", "markerfacecolor": "black", "markeredgecolor": "none", "markersize": 3}, boxprops={'facecolor': 'none', 'edgecolor': 'k'}, width=width, orient=orientation) - else: + elif agg_type == "multi": xy = {"x": self.model_type_dim, "y": 0} if orientation == "v" else {"x": 0, "y": self.model_type_dim} sns.boxplot(data=data_table.stack(self.model_type_dim).reset_index(), ax=ax, whis=1.5, palette=color_palette, showmeans=True, meanprops={"markersize": 6, "markeredgecolor": "k", "markerfacecolor": "white"}, @@ -1187,33 +1189,69 @@ class PlotSampleUncertaintyFromBootstrap(AbstractPlotClass): # pragma: no cover _labels = [str(i) + self.sampling for i in data_table.index.levels[1].values] handles, _ = ax.get_legend_handles_labels() ax.legend(handles, _labels) + else: + xy = (self.model_type_dim, 0) if orientation == "v" else (0, self.model_type_dim) + col_or_row = {"col": self.ahead_dim} if orientation == "v" else {"row": self.ahead_dim} + aspect = figsize[0] / figsize[1] + height = figsize[1] * 0.8 + ax = sns.FacetGrid(data_table.stack(self.model_type_dim).reset_index(), **col_or_row, aspect=aspect, height=height) + ax.map(sns.boxplot, *xy, whis=1.5, color="white", showmeans=True, order=data_table.mean().index.to_list(), + meanprops={"markersize": 6, "markeredgecolor": "k"}, + flierprops={"marker": "o", "markerfacecolor": "black", "markeredgecolor": "none", "markersize": 3}, + boxprops={'facecolor': 'none', 'edgecolor': 'k'}, width=width, orient=orientation) - if orientation == "v": - if apply_u_test: - ax = self.set_significance_bars(asteriks, ax, data_table, orientation) - ylims = list(ax.get_ylim()) - ax.set_ylim([ylims[0], ylims[1]*1.025]) - ax.set_ylabel(f"{self.error_measure} (in {self.error_unit})") - ax.set_xticklabels(ax.get_xticklabels(), rotation=45) - elif orientation == "h": - if apply_u_test: - ax = self.set_significance_bars(asteriks, ax, data_table, orientation) - ax.set_xlabel(f"{self.error_measure} (in {self.error_unit})") - xlims = list(ax.get_xlim()) - ax.set_xlim([xlims[0], xlims[1] * 1.015]) + _labels = [str(i) + self.sampling for i in data_table.index.levels[1].values] + for axi, title in zip(ax.axes.flatten(), _labels): + axi.set_title(title) + plt.setp(axi.lines, color='k') + + if agg_type == "panel": + if orientation == "v": + for axi in ax.axes.flatten(): + axi.set_xlabel(None) + axi.set_xticklabels(axi.get_xticklabels(), rotation=45) + ax.set_ylabels(f"{self.error_measure} (in {self.error_unit})") + loc = "upper left" + else: + for axi in ax.axes.flatten(): + axi.set_ylabel(None) + ax.set_xlabels(f"{self.error_measure} (in {self.error_unit})") + loc = "upper right" + text = f"n={n_boots}" + if self.block_length is not None: + text = f"{self.block_length}, {text}" + if len(season) > 0: + text = f"{season}, {text}" + text_box = AnchoredText(text, frameon=True, loc=loc) + plt.setp(text_box.patch, edgecolor='k', facecolor='w') + ax.axes.flatten()[0].add_artist(text_box) else: - raise ValueError(f"orientation must be `v' or `h' but is: {orientation}") - text = f"n={n_boots}" - if self.block_length is not None: - text = f"{self.block_length}, {text}" - if len(season) > 0: - text = f"{season}, {text}" - loc = "lower left" - text_box = AnchoredText(text, frameon=True, loc=loc, pad=0.5, bbox_to_anchor=(0., 1.0), - bbox_transform=ax.transAxes) - plt.setp(text_box.patch, edgecolor='k', facecolor='w') - ax.add_artist(text_box) - plt.setp(ax.lines, color='k') + if orientation == "v": + if apply_u_test: + ax = self.set_significance_bars(asteriks, ax, data_table, orientation) + ylims = list(ax.get_ylim()) + ax.set_ylim([ylims[0], ylims[1]*1.025]) + ax.set_ylabel(f"{self.error_measure} (in {self.error_unit})") + ax.set_xticklabels(ax.get_xticklabels(), rotation=45) + elif orientation == "h": + if apply_u_test: + ax = self.set_significance_bars(asteriks, ax, data_table, orientation) + ax.set_xlabel(f"{self.error_measure} (in {self.error_unit})") + xlims = list(ax.get_xlim()) + ax.set_xlim([xlims[0], xlims[1] * 1.015]) + else: + raise ValueError(f"orientation must be `v' or `h' but is: {orientation}") + text = f"n={n_boots}" + if self.block_length is not None: + text = f"{self.block_length}, {text}" + if len(season) > 0: + text = f"{season}, {text}" + loc = "lower left" + text_box = AnchoredText(text, frameon=True, loc=loc, pad=0.5, bbox_to_anchor=(0., 1.0), + bbox_transform=ax.transAxes) + plt.setp(text_box.patch, edgecolor='k', facecolor='w') + ax.add_artist(text_box) + plt.setp(ax.lines, color='k') plt.tight_layout() self._save() plt.close("all") diff --git a/mlair/plotting/tracker_plot.py b/mlair/plotting/tracker_plot.py index 53ec7496e7e04da0f53b1d0ce817793dea732963..5c5887a6e1f9b03ed06ade49a49cd70edc51e820 100644 --- a/mlair/plotting/tracker_plot.py +++ b/mlair/plotting/tracker_plot.py @@ -319,8 +319,12 @@ class TrackPlot: x_max = None if chain.successor is not None: + stage_count = 0 for e in chain.successor: if e.stage == stage: + stage_count += 1 + if stage_count > 50: + continue shift = self.width + self.space_intern_x if chain.stage == e.stage else 0 x_tmp = self.plot_track_chain(e, y_pos, x_pos + shift, prev=(x, y), stage=stage, sparse_conn_mode=sparse_conn_mode) diff --git a/mlair/run_modules/run_environment.py b/mlair/run_modules/run_environment.py index 2bc81750bf86d60e0c59bbf0fef68ae9c29138c9..9edb0aa27379cc2477e0240c43e4745ab5db1ce2 100644 --- a/mlair/run_modules/run_environment.py +++ b/mlair/run_modules/run_environment.py @@ -8,6 +8,7 @@ import logging import os import shutil import time +import sys from mlair.helpers.datastore import DataStoreByScope as DataStoreObject from mlair.helpers.datastore import NameNotFoundInDataStore @@ -160,8 +161,12 @@ class RunEnvironment(object): json.dump(tracker, f) def __plot_tracking(self): - plot_folder, plot_name = os.path.split(self.__find_file_pattern("tracking_%03i.pdf")) - TrackPlot(self.tracker_list, sparse_conn_mode=True, plot_folder=plot_folder, plot_name=plot_name) + try: + plot_folder, plot_name = os.path.split(self.__find_file_pattern("tracking_%03i.pdf")) + TrackPlot(self.tracker_list, sparse_conn_mode=True, plot_folder=plot_folder, plot_name=plot_name) + except Exception as e: + logging.info(f"Could not plot tracking plot due to:\n{sys.exc_info()[0]}\n" + f"{sys.exc_info()[1]}\n{sys.exc_info()[2]}") def __find_file_pattern(self, name): counter = 0