diff --git a/mlair/plotting/postprocessing_plotting.py b/mlair/plotting/postprocessing_plotting.py index fc3aa055679b2ad1f03719c6300b59f7ca2371c2..c22fa77009db0a9df533c8787e14f6e7343e09af 100644 --- a/mlair/plotting/postprocessing_plotting.py +++ b/mlair/plotting/postprocessing_plotting.py @@ -1119,12 +1119,14 @@ class PlotSampleUncertaintyFromBootstrap(AbstractPlotClass): # pragma: no cover # plot raw metric (mse) for orientation, utest, agg_type in variants: self._plot(orientation=orientation, apply_u_test=utest, agg_type=agg_type, season=_season) + self._plot_kde(agg_type=agg_type, season=_season) if apply_root is True: # plot root of metric (rmse) self._apply_root() for orientation, utest, agg_type in variants: self._plot(orientation=orientation, apply_u_test=utest, agg_type=agg_type, tag="_sqrt", season=_season) + self._plot_kde(agg_type=agg_type, tag="_sqrt", season=_season) self._data_table = None self._n_boots = None @@ -1153,6 +1155,60 @@ class PlotSampleUncertaintyFromBootstrap(AbstractPlotClass): # pragma: no cover self.error_measure = f"root {self.error_measure}" self.error_unit = self.error_unit.replace("$^2$", "") + def _plot_kde(self, agg_type="single", tag="", season=""): + self.plot_name = self.default_plot_name + "_kde" + "_" + agg_type + tag + {"": ""}.get(season, f"_{season}") + data_table = self._data_table + if agg_type == "multi": + return # nothing to do + if self.ahead_dim not in data_table.index.names and agg_type == "panel": + return # nothing to do + n_boots = self._n_boots + error_label = self.error_measure if self.error_unit is None else f"{self.error_measure} (in {self.error_unit})" + if agg_type == "single": + fig, ax = plt.subplots() + if self.ahead_dim in data_table.index.names: + data_table = data_table.groupby(level=0).mean() + sns.kdeplot(data=data_table, ax=ax) + ylims = list(ax.get_ylim()) + ax.set_ylim([ylims[0], ylims[1]*1.025]) + ax.set_xlabel(error_label) + + 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 = "upper 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) + ax.get_legend().set_title(None) + plt.tight_layout() + else: + g = sns.FacetGrid(data_table.stack(self.model_type_dim).reset_index(), **{"col": self.ahead_dim}, + hue=self.model_type_dim, legend_out=True) + g.map(sns.kdeplot, 0) + g.add_legend(title="") + fig = plt.gcf() + _labels = [str(i) + self.sampling for i in data_table.index.levels[1].values] + for axi, title in zip(g.axes.flatten(), _labels): + axi.set_title(title) + for axi in g.axes.flatten(): + axi.set_xlabel(None) + fig.supxlabel(error_label) + 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 = "upper right" + text_box = AnchoredText(text, frameon=True, loc=loc) + plt.setp(text_box.patch, edgecolor='k', facecolor='w') + g.axes.flatten()[0].add_artist(text_box) + self._save() + plt.close("all") + def _plot(self, orientation: str = "v", apply_u_test: bool = False, agg_type="single", tag="", season=""): self.plot_name = self.default_plot_name + {"v": "_vertical", "h": "_horizontal"}[orientation] + \ {True: "_u_test", False: ""}[apply_u_test] + "_" + agg_type + tag + \