smashbox.plot.myplot

   1import matplotlib.pyplot as plt
   2import numpy as np
   3import mpld3  # à ajouter dans le build du module
   4
   5from smashbox.tools import tools
   6from smashbox.stats import stats
   7from smashbox.plot import plot
   8from smashbox.plot import myplot
   9from smashbox.model import smash_model
  10from smashbox.tools import geo_toolbox
  11
  12
  13class myplot:
  14    """Class that provide some plotting functions. Plot can be displayed with matplolib UI
  15    or as html web page. Every plot can be saved into files."""
  16
  17    def __init__(self, parent_class):
  18        """
  19        Initialisation.
  20        :param parent_class: The parent class src.model.model() to be able to access to
  21         the smash model
  22        :type parent_class: src.model.model()
  23        """
  24        self._parent_class = parent_class
  25        """The parent class src.model.model() to be able to access to the smash model"""
  26
  27        self._target = "mysmashmodel"
  28        """The target to plot. Default is mysmashmodel"""
  29
  30        self._plot_object = getattr(self._parent_class, self._target)
  31        """The target object to plot. Default is mysmashmodel"""
  32
  33    @property
  34    def target(self):
  35        """Property: The target object to plot. Default is mysmashmodel"""
  36        return self._target
  37
  38    @target.setter
  39    def target(self, target):
  40        """Setter: The target object to plot. Default is mysmashmodel"""
  41        valid_target = [
  42            "mymesh",
  43            "mysmashmodel",
  44            "optimize_model",
  45            "validation_model",
  46            "warmup_model",
  47        ]
  48
  49        if target in valid_target:
  50            self._target = target
  51        else:
  52            raise ValueError(
  53                f"The target {target} is not valid. Choice are {valid_target}"
  54            )
  55            return
  56
  57        self._plot_object = getattr(self._parent_class, target)
  58
  59    def plot_mesh(
  60        self,
  61        coef_hydro: float = 99.0,
  62        ax_settings: dict = {},
  63        fig_settings: dict = {},
  64        html_show: bool = False,
  65    ):
  66        """
  67        Plot the map of the mesh of the Smash model with teh outlets and the hydrographic
  68        network.
  69        :param coef_hydro: couloring cells where the surface is higher than `coef_hydro`%
  70         of the total surface catchment, defaults to 99.0
  71        :type coef_hydro: float, optional
  72        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
  73         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  74        :type ax_settings: dict, optional
  75        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
  76         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  77        :type fig_settings: dict, optional
  78        :param html_show: Display the figure in an html page with your navigator, defaults
  79         to False
  80        :type html_show: bool, optional
  81
  82        """
  83        default_ax_settings = plot.ax_properties(
  84            title="Mesh of the Smash model",
  85            xlabel="x_coords",
  86            ylabel="y_coords",
  87        )
  88        default_ax_settings.update(**ax_settings)
  89
  90        fig_settings = plot.fig_properties(**fig_settings)
  91
  92        if not hasattr(self._parent_class.mymesh, "mesh"):
  93            raise ValueError("No smash mesh found. Build the mesh first.")
  94
  95        fig, ax = plot.plot_mesh(
  96            self._parent_class.mymesh.mesh,
  97            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
  98            coef_hydro=coef_hydro,
  99            ax_settings=ax_settings,
 100            fig_settings=fig_settings,
 101        )
 102
 103        if fig_settings.figname is None:
 104            if tools.with_reticulate() or html_show:
 105                mpld3.show(fig, open_browser=True)
 106            else:
 107                fig.show()
 108
 109    def plot_catchment_surface_consistency(
 110        self,
 111        label: bool = True,
 112        ax_settings: dict = {},
 113        fig_settings: dict = {},
 114        plot_settings: dict = {},
 115        html_show: bool = False,
 116    ):
 117        """
 118        Plot the modeled surface vs the observed surface. Check its consistency.
 119         :param label, labels the point on the plot with the code of the outlets.
 120         :type label: bool, default True
 121        :param ax_settings, any properties of plot.ax_properties() class can be defined
 122         in this dictionnary, defaults to {}
 123        :type ax_settings: dict, optional
 124        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 125         plot.fig_properties() class can be defined in this dictionnary, defaults to {}
 126        :type fig_settings: dict, optional
 127        :param plot_settings,  any properties of plot.plot_properties() class can be
 128        defined in this dictionnary, defaults to {}
 129        :param html_show: Display the figure in an html page with your navigator, defaults
 130         to False
 131        :type html_show: bool, optional
 132
 133        """
 134
 135        default_ax_settings = plot.ax_properties(
 136            title="Modeled and observed surface consistency",
 137            xlabel="Observed surface",
 138            ylabel="Modeled surface",
 139        )
 140        default_ax_settings.update(**ax_settings)
 141
 142        fig_settings = plot.fig_properties(**fig_settings)
 143
 144        if not hasattr(self._parent_class.mymesh, "mesh"):
 145            raise ValueError("No smash mesh found. Build the mesh first.")
 146
 147        fig, ax = plot.plot_catchment_surface_consistency(
 148            mesh=self._parent_class.mymesh.mesh,
 149            label=label,
 150            ax_settings=ax_settings,
 151            fig_settings=fig_settings,
 152            plot_settings=plot_settings,
 153        )
 154
 155        if fig_settings.figname is None:
 156            if tools.with_reticulate() or html_show:
 157                mpld3.show(fig, open_browser=True)
 158            else:
 159                fig.show()
 160
 161    def plot_catchment_surface_error(
 162        self,
 163        ax_settings: dict = {},
 164        fig_settings: dict = {},
 165        html_show: bool = False,
 166    ):
 167        """
 168        Plot the modeled surface vs the observed surface. Check its consistency.
 169         :param ax_settings, any properties of plot.ax_properties() class can be defined
 170         in this dictionnary, defaults to {}
 171        :type ax_settings: dict, optional
 172        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 173         plot.fig_properties() class can be defined in this dictionnary, defaults to {}
 174        :param html_show: Display the figure in an html page with your navigator, defaults
 175         to False
 176        :type html_show: bool, optional
 177
 178        """
 179
 180        default_ax_settings = plot.ax_properties(
 181            title="Catchment surface error",
 182            xlabel="Catchments",
 183            ylabel="(Ssim - Sobs)/Sobs",
 184        )
 185        default_ax_settings.update(**ax_settings)
 186
 187        fig_settings = plot.fig_properties(**fig_settings)
 188
 189        if not hasattr(self._parent_class.mymesh, "mesh"):
 190            raise ValueError("No smash mesh found. Build the mesh first.")
 191
 192        fig, ax = plot.plot_catchment_surface_error(
 193            mesh=self._parent_class.mymesh.mesh,
 194            ax_settings=ax_settings,
 195            fig_settings=fig_settings,
 196        )
 197
 198        if fig_settings.figname is None:
 199            if tools.with_reticulate() or html_show:
 200                mpld3.show(fig, open_browser=True)
 201            else:
 202                fig.show()
 203
 204    @tools.autocast_args
 205    def plot_xy_quantile(
 206        self,
 207        duration: int = 1,
 208        X: int = 0,
 209        Y: int = 0,
 210        ax_settings: dict = {},
 211        fig_settings: dict = {},
 212        plot_settings: dict = {},
 213        html_show: bool = False,
 214    ):
 215        """
 216
 217        :param duration: Duration of the quantile, defaults to 1
 218        :type duration: int, optional
 219        :param X: X coordinate of the targeted cell (matrix coordinate system), defaults
 220         to 0
 221        :type X: int, optional
 222        :param Y: Y coordinate of the targeted cell (matrix coordinate system), defaults
 223        to 0
 224        :type Y: int, optional
 225        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 226         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 227        :type ax_settings: dict, optional
 228        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 229        plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 230        :type fig_settings: dict, optional
 231        :param html_show: Display the figure in an html page with your navigator,
 232         defaults to False
 233        :type html_show: bool, optional
 234
 235        """
 236
 237        if not hasattr(
 238            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 239        ):
 240            raise ValueError(
 241                f"No statistical results found for duration {duration}h"
 242            )
 243
 244        results_quantile = getattr(
 245            self._plot_object.mystats.quantile_stats,
 246            f"Quantile_{duration}h",
 247        )
 248
 249        if self._plot_object.smash.mesh.active_cell[X, Y] == 0:
 250            raise ValueError(
 251                f"`{X},{Y}` coordinates does not correspond to an active cell."
 252            )
 253
 254        default_ax_settings = plot.ax_properties(
 255            title=f"Maximal discharges frequency curve on {results_quantile.chunk_size}"
 256            " days",
 257            xscale="log",
 258            xlabel=f"Return period (*{results_quantile.chunk_size} days)",
 259            ylabel="Discharges (m³/s)",
 260            grid=True,
 261            legend=True,
 262        )
 263        default_ax_settings.update(**ax_settings)
 264
 265        fig_settings = plot.fig_properties(**fig_settings)
 266
 267        fig, ax = plot.plot_xy_quantile(
 268            results_quantile.__dict__,
 269            X,
 270            Y,
 271            ax_settings=default_ax_settings,
 272            fig_settings=fig_settings,
 273            plot_settings=plot_settings,
 274        )
 275
 276        if fig_settings.figname is None:
 277            if tools.with_reticulate() or html_show:
 278                mpld3.show(fig, open_browser=True)
 279            else:
 280                fig.show()
 281        # return fig, ax
 282
 283    @tools.autocast_args
 284    def plot_outlets_quantile(
 285        self,
 286        duration: int = 1,
 287        quantile_obs=True,
 288        gauge: list | None = None,
 289        ax_settings: dict = {},
 290        fig_settings: dict = {},
 291        plot_settings: dict = {},
 292        html_show: bool = False,
 293    ):
 294        """
 295        Plot the quantiles prediction for different return period for every outlets.
 296        :param duration: Duration of the quantile, defaults to 1
 297        :type duration: int, optional
 298        :param quantile_obs: Compute and display the observed quantile in th graphics.
 299        Observed quantile are computed again the whole observed discharge chronicle
 300        from 1900 until today.
 301        :type quantile_obs: Bool, default is True
 302        :param gauge: List of gauge code to plot. Default is None. If None all gague
 303        are plotted
 304        :type gauge: list | None, default None.
 305        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 306         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 307        :type ax_settings: dict, optional
 308        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 309         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 310        :type fig_settings: dict, optional
 311        :param plot_settings: Parameters of the matplotlib figure 'fig'. Any properties of
 312         plot.plot_settings() class ca be defined in this dictionnary, defaults to {}
 313        :type plot_settings: dict, optional
 314        :param html_show: Display the figure in an html page with your navigator, defaults
 315        to False
 316        :type html_show: bool, optional
 317
 318        """
 319
 320        # fig_settings = plot.fig_properties(**fig_settings)
 321
 322        if not hasattr(
 323            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 324        ):
 325            raise ValueError(
 326                f"No statistical results found for duration {duration}h"
 327            )
 328
 329        gauge_pos = list(self._plot_object.smash.mesh.gauge_pos)
 330        gauge_code = list(self._plot_object.smash.mesh.code)
 331
 332        if gauge is not None:
 333            list_ind_gauge = []
 334            for i, g in enumerate(gauge_code):
 335                if g in gauge:
 336                    list_ind_gauge.append(i)
 337                else:
 338                    print(
 339                        f"</> gauge {g} not found in the mesh gauge list {gauge_code}"
 340                    )
 341            if len(list_ind_gauge) > 0:
 342                gauge_pos = gauge_pos[list_ind_gauge]
 343                gauge_code = gauge_code[list_ind_gauge]
 344            else:
 345                print(
 346                    f"</> gauge {gauge} not found in the mesh gauge list {gauge_code}"
 347                )
 348
 349        yfig = int(np.sqrt(len(gauge_pos)))
 350        xfig = int(np.ceil(len(gauge_pos) / yfig))
 351
 352        default_fig_settings = plot.fig_properties(
 353            ysize=yfig * 5, xsize=xfig * 3
 354        )
 355        default_fig_settings.update(**fig_settings)
 356
 357        if quantile_obs:
 358            res_quantile_obs = stats.quantil_obs(
 359                qobs_directory=self._plot_object.smash.setup.qobs_directory,
 360                code=gauge_code,
 361                model_time_step=self._plot_object.smash.setup.dt,
 362                quantile_duration=duration,
 363            )
 364        else:
 365            res_quantile_obs = None
 366
 367        fig, axs = plt.subplots(
 368            xfig,
 369            yfig,
 370            constrained_layout=True,
 371        )
 372
 373        for ax, coords, code in zip(axs.flat, gauge_pos, gauge_code):
 374
 375            X, Y = coords
 376            results_quantile = getattr(
 377                self._plot_object.mystats.quantile_stats,
 378                f"Quantile_{duration}h",
 379            )
 380
 381            # default_ax_settings = plot.ax_properties(
 382            #     title=f"Discharges quantile at gauge {code}",
 383            #     legend_fontsize=6,
 384            # )
 385            # default_ax_settings.update(**ax_settings)
 386
 387            default_ax_settings = plot.ax_properties(
 388                title=f"Discharges quantile at gauge {code}",
 389                xscale="log",
 390                xlabel=f"Return period (*{results_quantile.chunk_size} days)",
 391                ylabel="Discharges (m³/s)",
 392                grid=True,
 393                legend=True,
 394                legend_fontsize=8,
 395                xtics_fontsize=8,
 396                ytics_fontsize=8,
 397            )
 398            default_ax_settings.update(**ax_settings)
 399
 400            default_plot_settings = plot.plot_properties(
 401                markersize=6,
 402            )
 403            default_plot_settings.update(**plot_settings)
 404
 405            fig, ax = plot.plot_xy_quantile(
 406                results_quantile.__dict__,
 407                X,
 408                Y,
 409                res_quantile_obs=res_quantile_obs,
 410                gauge_pos=list(gauge_code).index(code),
 411                figure=[fig, ax],
 412                ax_settings=default_ax_settings,
 413                plot_settings=default_plot_settings,
 414            )
 415
 416        default_fig_settings.change((fig, axs))
 417
 418        if default_fig_settings.figname is None:
 419            if tools.with_reticulate() or html_show:
 420                mpld3.show(fig, open_browser=True)
 421            else:
 422                fig.show()
 423
 424        # return fig, axs
 425
 426    @tools.autocast_args
 427    def plot_spatial_quantile(
 428        self,
 429        duration: int = 1,
 430        T: int = 2,
 431        vmin: float | None = 0,
 432        vmax: float | None = None,
 433        ax_settings: dict = {},
 434        fig_settings: dict = {},
 435        html_show=False,
 436    ):
 437        """
 438        Plot the map of the quantiles for given return period and a given duration.
 439        :param duration: Duration of the quantile, defaults to 1
 440        :type duration: int, optional
 441        :param T: return period, defaults to 2 (default is years, but that depends
 442         of the chunk size)
 443        :type T: int, optional
 444        :param vmin: Minimal bounds value for the colorbar, defaults to 0
 445        :type vmin: float, optional
 446        :param vmax: Maximal bounds value for the colorbar, defaults to None
 447        :type vmax: float, optional
 448        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 449         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 450        :type ax_settings: dict, optional
 451        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 452         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 453        :type fig_settings: dict, optional
 454        :param html_show: Display the figure in an html page with your navigator, defaults to False
 455        :type html_show: bool, optional
 456
 457        """
 458
 459        fig_settings = plot.fig_properties(**fig_settings)
 460
 461        if not hasattr(
 462            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 463        ):
 464            raise ValueError(
 465                f"No statistical results found for duration {duration}h"
 466            )
 467
 468        results_quantile = getattr(
 469            self._plot_object.mystats.quantile_stats,
 470            f"Quantile_{duration}h",
 471        )
 472
 473        default_ax_settings = plot.ax_properties(
 474            title=f"Discharges quantile for duration={duration} h, T={T}",
 475            xlabel="Coords X",
 476            ylabel="Coords_Y",
 477            clabel="Discharge (m^3/s)",
 478            cmap="viridis",
 479        )
 480        default_ax_settings.update(**ax_settings)
 481
 482        z = list(results_quantile.T).index(T)
 483
 484        fig, ax = plot.plot_image(
 485            matrice=results_quantile.Q_th[:, :, z],
 486            bbox=geo_toolbox.get_bbox_from_smash_mesh(
 487                self._parent_class.mymesh.mesh
 488            ),
 489            vmin=vmin,
 490            vmax=vmax,
 491            mask=self._plot_object.smash.mesh.active_cell,
 492            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
 493            ax_settings=default_ax_settings,
 494            fig_settings=fig_settings,
 495        )
 496
 497        if fig_settings.figname is None:
 498            if tools.with_reticulate() or html_show:
 499                mpld3.show(fig, open_browser=True)
 500            else:
 501                fig.show()
 502
 503        # return fig, ax
 504
 505    @tools.autocast_args
 506    def multiplot_spatial_quantile(
 507        self,
 508        duration: int = 1,
 509        vmin: float | None = 0,
 510        vmax: float | None = None,
 511        ax_settings={},
 512        fig_settings={},
 513        html_show: bool = False,
 514    ):
 515        """
 516        Plot the map of the quantiles for every return period for a given duration.
 517        :param duration: Duration of the quantile, defaults to 1
 518        :type duration: int, optional
 519        :param vmin: Minimal bounds value for the colorbar, defaults to 0
 520        :type vmin: float, optional
 521        :param vmax: Maximal bounds value for the colorbar, defaults to None
 522        :type vmax: float, optional
 523        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 524         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 525        :type ax_settings: dict, optional
 526        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 527         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 528        :type fig_settings: dict, optional
 529        :param html_show: Display the figure in an html page with your navigator, defaults
 530         to False
 531        :type html_show: bool, optional
 532
 533        """
 534
 535        fig_settings = plot.fig_properties(**fig_settings)
 536
 537        if not hasattr(
 538            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 539        ):
 540            raise ValueError(
 541                f"No statistical results found for duration {duration}h"
 542            )
 543
 544        results_quantile = getattr(
 545            self._plot_object.mystats.quantile_stats,
 546            f"Quantile_{duration}h",
 547        )
 548
 549        yfig = int(np.sqrt(len(results_quantile.T)))
 550        xfig = int(np.ceil(len(results_quantile.T) / yfig))
 551
 552        fig, axs = plt.subplots(
 553            xfig,
 554            yfig,
 555            constrained_layout=False,
 556        )
 557        plt.subplots_adjust(
 558            left=None,
 559            bottom=None,
 560            right=None,
 561            top=None,
 562            wspace=0.5,
 563            hspace=None,
 564        )
 565
 566        for ax, T in zip(axs.flat, results_quantile.T):
 567
 568            default_ax_settings = plot.ax_properties(
 569                title=f"Discharges quantile for duration={duration} h, T={T}",
 570                xlabel="Coords X",
 571                ylabel="Coords_Y",
 572                clabel="Discharge (m^3/s)",
 573                cmap="viridis",
 574                title_fontsize=10,
 575                label_fontsize=8,
 576                xtics_fontsize=6,
 577                ytics_fontsize=6,
 578            )
 579            default_ax_settings.update(**ax_settings)
 580
 581            z = list(results_quantile.T).index(T)
 582
 583            fig, ax = plot.plot_image(
 584                matrice=results_quantile.Q_th[:, :, z],
 585                bbox=geo_toolbox.get_bbox_from_smash_mesh(
 586                    self._parent_class.mymesh.mesh
 587                ),
 588                vmin=vmin,
 589                vmax=vmax,
 590                mask=self._plot_object.smash.mesh.active_cell,
 591                catchment_polygon=self._parent_class.mymesh.catchment_polygon,
 592                ax_settings=default_ax_settings,
 593                figure=[fig, ax],
 594            )
 595
 596        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
 597        fig_settings.change((fig, axs))
 598
 599        if fig_settings.figname is None or html_show:
 600            if tools.with_reticulate():
 601                mpld3.show(fig, open_browser=True)
 602            else:
 603                fig.show()
 604
 605        # return fig, axs
 606
 607    def plot_spatial_stats(
 608        self,
 609        stats: str = "max",
 610        vmin: float | None = 0,
 611        vmax: float | None = None,
 612        ax_settings: dict = {},
 613        fig_settings: dict = {},
 614        html_show: bool = False,
 615    ):
 616        """
 617        Plot the map of a given spatial statistic.
 618        :param stats: The statistic to plot, choice are
 619         'max, min, mean, median, q20, q80', defaults to "max"
 620        :type stats: str, optional
 621        ::param vmin: Minimal bounds value for the colorbar, defaults to 0
 622        :type vmin: float, optional
 623        :param vmax: Maximal bounds value for the colorbar, defaults to None
 624        :type vmax: float, optional
 625        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 626         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 627        :type ax_settings: dict, optional
 628        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 629         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 630        :type fig_settings: dict, optional
 631        :param html_show: Display the figure in an html page with your navigator, defaults
 632         to False
 633        :type html_show: bool, optional
 634
 635        """
 636
 637        fig_settings = plot.fig_properties(**fig_settings)
 638
 639        if not hasattr(self._plot_object.mystats.spatial_stats.results, stats):
 640            raise ValueError(
 641                f"Statistical results `{stats}` not found. Choice are: "
 642                "[min, max, mean, median, q20, q80]"
 643            )
 644
 645        stats_matrix = getattr(
 646            self._plot_object.mystats.spatial_stats.results,
 647            stats,
 648        )
 649        default_ax_settings = plot.ax_properties(
 650            title="Maximal Discharges on periode"
 651            f" {self._plot_object.smash.setup.start_time} -"
 652            f" {self._plot_object.smash.setup.end_time}",
 653            xlabel="Coords X",
 654            ylabel="Coords_Y",
 655            clabel="Discharge (m^3/s)",
 656            cmap="viridis",
 657        )
 658        default_ax_settings.update(**ax_settings)
 659
 660        fig, ax = plot.plot_image(
 661            matrice=stats_matrix,
 662            bbox=geo_toolbox.get_bbox_from_smash_mesh(
 663                self._parent_class.mymesh.mesh
 664            ),
 665            vmin=vmin,
 666            vmax=vmax,
 667            mask=self._plot_object.smash.mesh.active_cell,
 668            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
 669            ax_settings=default_ax_settings,
 670            fig_settings=fig_settings,
 671        )
 672
 673        if fig_settings.figname is None:
 674            if tools.with_reticulate() or html_show:
 675                mpld3.show(fig, open_browser=True)
 676            else:
 677                fig.show()
 678
 679        # return fig, ax
 680
 681    def plot_hydrograph(
 682        self,
 683        columns: list | None = [],
 684        outlets_name: list = [],
 685        plot_rainfall: bool = True,
 686        ax_settings: dict = {},
 687        fig_settings: dict = {},
 688        plot_settings_sim: dict = {},
 689        plot_settings_obs: dict = {},
 690        html_show: bool = False,
 691    ):
 692        """
 693        Plot the simulated and the observed hydrogram for different outlets.
 694
 695        :param columns: Columns of the matrix to plot (outlets), defaults to []
 696        :type columns: list | None, optional
 697        :param outlets_name: List of the outlets name to plot, defaults to []
 698        :type outlets_name: list, optional
 699        :param plot_rainfall: Plot the rainfall on the graphics, defaults to True
 700        :type plot_rainfall: bool, optional
 701        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 702         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 703        :type ax_settings: dict, optional
 704        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 705         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 706        :type fig_settings: dict, optional
 707        :param plot_settings_sim: Parameters of the matplotlib curves. Any propoerties of
 708         plot.plot_properties() class ca be defined in this dictionnary, defaults to {}
 709        :type plot_settings_sim: dict, optional
 710        :param plot_settings_obs: DParameters of the matplotlib curves. Any propoerties of
 711         plot.plot_properties() class ca be defined in this dictionnary, defaults to {}
 712        :type plot_settings_obs: dict, optional
 713        :pparam html_show: Display the figure in an html page with your navigator, defaults
 714         to False
 715        :type html_show: bool, optional
 716
 717        """
 718
 719        fig_settings = plot.fig_properties(**fig_settings)
 720
 721        if len(outlets_name) > 0:
 722            columns = tools.array_isin(
 723                self._plot_object.smash.mesh.code,
 724                np.array(outlets_name),
 725            )
 726        elif len(columns) > 0:
 727            outlets_name = [
 728                self._plot_object.smash.mesh.code[i] for i in columns
 729            ]
 730
 731        if columns is None:
 732            columns = list(
 733                range(0, self._plot_object.smash.response.q.shape[0])
 734            )
 735            outlets_name = list(self._plot_object.smash.mesh.code)
 736
 737        if len(columns) == 0:
 738            columns = [0]
 739            outlets_name = [list(self._plot_object.smash.mesh.code)[0]]
 740
 741        fig, ax = plot.plot_hydrograph(
 742            model=self._plot_object.smash,
 743            columns=columns,
 744            outlets_name=outlets_name,
 745            plot_rainfall=plot_rainfall,
 746            ax_settings=ax_settings,
 747            fig_settings=fig_settings,
 748            plot_settings_sim=plot_settings_sim,
 749            plot_settings_obs=plot_settings_obs,
 750        )
 751
 752        if fig_settings.figname is None:
 753            if tools.with_reticulate() or html_show:
 754                mpld3.show(fig, open_browser=True)
 755            else:
 756                fig.show()
 757
 758        # return fig, ax
 759
 760    def plot_misfit(
 761        self,
 762        columns: list | None = None,
 763        outlets_name: list = [],
 764        misfit: str = "nse",
 765        ax_settings: dict = {},
 766        fig_settings: dict = {},
 767        html_show: bool = False,
 768    ):
 769        """
 770        Plot a misfit criteria for a given list of outlet.
 771        :param columns: Columns of the matrix to plot (outlets), defaults to []
 772        :type columns: list | None, optional
 773        :param outlets_name: List of the outlets name to plot, defaults to []
 774        :type outlets_name: list, optional
 775        :param misfit: The misfit criteria to plot, choice are
 776        "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
 777        :type misfit: str, optional
 778        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 779         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 780        :type ax_settings: dict, optional
 781        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 782         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 783        :type fig_settings: dict, optional
 784        :param html_show: Display the figure in an html page with your navigator, defaults
 785         to False
 786        :type html_show: bool, optional
 787
 788        """
 789
 790        fig_settings = plot.fig_properties(**fig_settings)
 791
 792        values = getattr(
 793            self._plot_object.mystats.misfit_stats.results, misfit
 794        )
 795
 796        if len(outlets_name) > 0:
 797            columns = tools.array_isin(
 798                self._plot_object.smash.mesh.code,
 799                np.array(outlets_name),
 800            )
 801
 802        if columns is None:
 803            columns = list(
 804                range(0, self._plot_object.smash.response.q.shape[0])
 805            )
 806            outlets_name = self._plot_object.smash.mesh.code
 807
 808        fig, ax = plot.plot_misfit(
 809            values=values[columns],
 810            names=outlets_name,
 811            columns=None,
 812            misfit=misfit,
 813            ax_settings=ax_settings,
 814            fig_settings=fig_settings,
 815        )
 816
 817        if fig_settings.figname is None:
 818            if tools.with_reticulate() or html_show:
 819                mpld3.show(fig, open_browser=True)
 820            else:
 821                fig.show()
 822
 823        # return fig, ax
 824
 825    def plot_outlet_stats(
 826        self,
 827        columns: list | None = None,
 828        outlets_name: list = [],
 829        stat: str = "max",
 830        ax_settings: dict = {},
 831        fig_settings: dict = {},
 832        html_show: bool = False,
 833    ):
 834        """
 835        Plot a statistical criteria for a given list of outlet.
 836        :param columns: Columns of the matrix to plot (outlets), defaults to []
 837        :type columns: list | None, optional
 838        :param outlets_name: List of the outlets name to plot, defaults to []
 839        :type outlets_name: list, optional
 840        :param misfit: The misfit criteria to plot, choice are
 841        "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
 842        :type misfit: str, optional
 843        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 844         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 845        :type ax_settings: dict, optional
 846        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 847         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 848        :type fig_settings: dict, optional
 849        :param html_show: Display the figure in an html page with your navigator, defaults
 850         to False
 851        :type html_show: bool, optional
 852
 853        """
 854
 855        fig_settings = plot.fig_properties(**fig_settings)
 856
 857        values_sim = getattr(
 858            self._plot_object.mystats.outlets_stats.results_sim, stat
 859        )
 860        values_obs = getattr(
 861            self._plot_object.mystats.outlets_stats.results_obs, stat
 862        )
 863
 864        if len(outlets_name) > 0:
 865            columns = tools.array_isin(
 866                self._plot_object.smash.mesh.code,
 867                np.array(outlets_name),
 868            )
 869
 870        if columns is None:
 871            columns = list(
 872                range(0, self._plot_object.smash.response.q.shape[0])
 873            )
 874            outlets_name = list(self._plot_object.smash.mesh.code)
 875
 876        fig, ax = plot.plot_outlet_stats(
 877            values_sim=values_sim[columns],
 878            values_obs=values_obs[columns],
 879            names=outlets_name,
 880            columns=None,
 881            stat=stat,
 882            ax_settings=ax_settings,
 883            fig_settings=fig_settings,
 884        )
 885
 886        if fig_settings.figname is None:
 887            if tools.with_reticulate() or html_show:
 888                mpld3.show(fig, open_browser=True)
 889            else:
 890                fig.show()
 891
 892        # return fig, ax
 893
 894    def multiplot_misfit(
 895        self,
 896        columns: list | None = None,
 897        outlets_name: list = [],
 898        misfit: list = [
 899            "nse",
 900            "nnse",
 901            "kge",
 902            "mse",
 903            "rmse",
 904            "nrmse",
 905            "se",
 906            "mae",
 907            "mape",
 908            "lgrm",
 909        ],
 910        ax_settings: dict = {},
 911        fig_settings: dict = {},
 912        html_show: bool = False,
 913    ):
 914        """
 915        Plot misfit criterium for a given list of outlets.
 916
 917        :param columns: Columns of the matrix to plot (outlets), defaults to []
 918        :type columns: list | None, optional
 919        :param outlets_name: List of the outlets name to plot, defaults to []
 920        :type outlets_name: list, optional
 921        :param misfit: The misfit criteria to plot, list of criteria among
 922        "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
 923        :type misfit: str, optional
 924        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 925         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 926        :type ax_settings: dict, optional
 927        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 928         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 929        :type fig_settings: dict, optional
 930        :param html_show: Display the figure in an html page with your navigator, defaults
 931         to False
 932        :type html_show: bool, optional
 933
 934        """
 935
 936        fig_settings = plot.fig_properties(**fig_settings)
 937
 938        if len(outlets_name) > 0:
 939            columns = tools.array_isin(
 940                self._plot_object.smash.mesh.code,
 941                np.array(outlets_name),
 942            )
 943
 944        if columns is None:
 945            columns = list(
 946                range(0, self._plot_object.smash.response.q.shape[0])
 947            )
 948            outlets_name = list(self._plot_object.smash.mesh.code)
 949
 950        yfig = int(np.sqrt(len(misfit)))
 951        xfig = int(np.ceil(len(misfit) / yfig))
 952
 953        fig, axs = plt.subplots(
 954            xfig,
 955            yfig,
 956            constrained_layout=True,
 957        )
 958
 959        # for ax in axs:
 960        #     ax.set_axis_off()
 961
 962        for ax, crit in zip(
 963            axs.flat,
 964            misfit,
 965        ):
 966
 967            # ax.set_axis_on()
 968            ax_settings["ylabel"] = f"{crit} criteria"
 969            ax_settings["title"] = f"{crit} criteria"
 970
 971            if hasattr(self._plot_object.mystats.misfit_stats.results, crit):
 972                values = getattr(
 973                    self._plot_object.mystats.misfit_stats.results, crit
 974                )
 975            else:
 976                raise ValueError(
 977                    f"`{crit}` is not a valid statistic. choice are:"
 978                    "[nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge]"
 979                )
 980
 981            fig, ax = plot.plot_misfit(
 982                values=values[columns],
 983                names=np.array(outlets_name),
 984                columns=None,
 985                misfit=crit,
 986                figure=(fig, ax),
 987                ax_settings=ax_settings,
 988            )
 989
 990        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
 991        fig_settings.change((fig, ax))
 992
 993        if fig_settings.figname is None:
 994            if tools.with_reticulate() or html_show:
 995                mpld3.show(fig, open_browser=True)
 996            else:
 997                fig.show()
 998
 999        # return fig, ax
1000
1001    def plot_misfit_map(
1002        self,
1003        misfit: str = "nse",
1004        coef_hydro: float = 99.0,
1005        ax_settings: dict = {},
1006        fig_settings: dict = {},
1007        plot_settings: dict = {},
1008        html_show: bool = False,
1009    ):
1010        """
1011        Plot a map of a misfit criteria.
1012
1013        :param columns: Columns of the matrix to plot (outlets), defaults to []
1014        :type columns: list | None, optional
1015        :param outlets_name: List of the outlets name to plot, defaults to []
1016        :type outlets_name: list, optional
1017        :param misfit: The misfit criteria to plot, choice are
1018        "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
1019        :type misfit: str, optional
1020        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1021         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1022        :type ax_settings: dict, optional
1023        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1024         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1025        :type fig_settings: dict, optional
1026        :param html_show: Display the figure in an html page with your navigator, defaults
1027         to False
1028        :type html_show: bool, optional
1029
1030        """
1031
1032        if hasattr(self._plot_object.mystats.misfit_stats.results, misfit):
1033            values = getattr(
1034                self._plot_object.mystats.misfit_stats.results, misfit
1035            )
1036        else:
1037            raise ValueError(
1038                f"`{misfit}` is not a valid statistic. choice are:"
1039                "[nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge]"
1040            )
1041
1042        fig_settings = plot.fig_properties(**fig_settings)
1043
1044        name = self._plot_object.smash.mesh.code
1045        mesh = self._parent_class.mymesh.mesh
1046
1047        fig, ax = plot.plot_misfit_map(
1048            values=values,
1049            names=name,
1050            mesh=mesh,
1051            misfit=misfit,
1052            coef_hydro=coef_hydro,
1053            ax_settings=ax_settings,
1054            fig_settings=fig_settings,
1055            plot_settings=plot_settings,
1056        )
1057
1058        if fig_settings.figname is None:
1059            if tools.with_reticulate() or html_show:
1060                mpld3.show(fig, open_browser=True)
1061            else:
1062                fig.show()
1063
1064        # return fig, ax
1065
1066    def multiplot_parameters(
1067        self,
1068        mask_active_cell=False,
1069        ax_settings={},
1070        fig_settings={},
1071        html_show: bool = False,
1072    ):
1073        """
1074        Multiplot map of every Smash parameters
1075        :param mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
1076        :type mask_active_cell: bool, False, optional
1077        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1078         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1079        :type ax_settings: dict, optional
1080        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1081         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1082        :type fig_settings: dict, optional
1083        :param html_show: Display the figure in an html page with your navigator, defaults
1084         to False
1085        :type html_show: bool, optional
1086
1087        """
1088
1089        default_fig_settings = plot.fig_properties(xsize=8, ysize=8)
1090        default_fig_settings.update(**fig_settings)
1091
1092        param = list(self._plot_object.smash.rr_parameters.keys)
1093
1094        if mask_active_cell:
1095            mask = self._plot_object.smash.mesh.active_cell
1096        else:
1097            mask = None
1098
1099        yfig = int(np.sqrt(len(param)))
1100        xfig = int(np.ceil(len(param) / yfig))
1101
1102        fig, axs = plt.subplots(
1103            xfig,
1104            yfig,
1105            constrained_layout=False,
1106        )
1107        plt.subplots_adjust(
1108            left=None,
1109            bottom=None,
1110            right=None,
1111            top=None,
1112            wspace=0.5,
1113            hspace=0.5,
1114        )
1115        for ax, p in zip(axs.flat, param):
1116
1117            default_ax_settings = plot.ax_properties(
1118                title=f"{p} parameters map",
1119                xlabel="Coords X",
1120                ylabel="Coords_Y",
1121                clabel=f"{p} parameter value",
1122                cmap="viridis",
1123            )
1124            default_ax_settings.update(**ax_settings)
1125
1126            z = param.index(p)
1127
1128            fig, ax = plot.plot_image(
1129                matrice=self._plot_object.smash.rr_parameters.values[:, :, z],
1130                bbox=geo_toolbox.get_bbox_from_smash_mesh(
1131                    self._parent_class.mymesh.mesh
1132                ),
1133                mask=mask,
1134                vmin=0.0,
1135                catchment_polygon=self._parent_class.mymesh.catchment_polygon,
1136                ax_settings=default_ax_settings,
1137                figure=[fig, ax],
1138            )
1139
1140        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
1141        default_fig_settings.change((fig, axs))
1142
1143        if default_fig_settings.figname is None or html_show:
1144            if tools.with_reticulate():
1145                mpld3.show(fig, open_browser=True)
1146            else:
1147                fig.show()
1148
1149        # return fig, axs
1150
1151    def plot_parameters(
1152        self,
1153        param="cp",
1154        mask_active_cell=False,
1155        vmin=0.0,
1156        vmax=None,
1157        ax_settings={},
1158        fig_settings={},
1159        html_show: bool = False,
1160    ):
1161        """
1162        Plot a map of a Smash parameters
1163        :param param: Name of the parameter to plot, defaults to "cp"
1164        :type param: str, optional
1165        :param mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
1166        :type mask_active_cell: bool, False, optional
1167        :param vmin: Minimum value of the colorbar, defaults to 0.0
1168        :type vmin: float, optional
1169        :param vmax: Maximum value of the colorbar, defaults to None
1170        :type vmax: float, optional
1171        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1172         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1173        :type ax_settings: dict, optional
1174        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1175         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1176        :type fig_settings: dict, optional
1177        :param html_show: Display the figure in an html page with your navigator, defaults
1178         to False
1179        :type html_show: bool, optional
1180        """
1181
1182        fig_settings = plot.fig_properties(**fig_settings)
1183
1184        list_param = list(self._plot_object.smash.rr_parameters.keys)
1185        z = list_param.index(param)
1186
1187        if mask_active_cell:
1188            mask = self._plot_object.smash.mesh.active_cell
1189        else:
1190            mask = None
1191
1192        fig, axs = plt.subplots()
1193
1194        default_ax_settings = plot.ax_properties(
1195            title=f"{param} parameters map",
1196            xlabel="Coords X",
1197            ylabel="Coords_Y",
1198            clabel=f"{param} parameter value",
1199            cmap="viridis",
1200        )
1201        default_ax_settings.update(**ax_settings)
1202
1203        fig, ax = plot.plot_image(
1204            matrice=self._plot_object.smash.rr_parameters.values[:, :, z],
1205            bbox=geo_toolbox.get_bbox_from_smash_mesh(
1206                self._parent_class.mymesh.mesh
1207            ),
1208            mask=mask,
1209            vmin=vmin,
1210            vmax=vmax,
1211            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
1212            ax_settings=default_ax_settings,
1213        )
1214
1215        fig_settings.change((fig, axs))
1216
1217        if fig_settings.figname is None or html_show:
1218            if tools.with_reticulate():
1219                mpld3.show(fig, open_browser=True)
1220            else:
1221                fig.show()
1222
1223        # return fig, axs
class myplot:
  14class myplot:
  15    """Class that provide some plotting functions. Plot can be displayed with matplolib UI
  16    or as html web page. Every plot can be saved into files."""
  17
  18    def __init__(self, parent_class):
  19        """
  20        Initialisation.
  21        :param parent_class: The parent class src.model.model() to be able to access to
  22         the smash model
  23        :type parent_class: src.model.model()
  24        """
  25        self._parent_class = parent_class
  26        """The parent class src.model.model() to be able to access to the smash model"""
  27
  28        self._target = "mysmashmodel"
  29        """The target to plot. Default is mysmashmodel"""
  30
  31        self._plot_object = getattr(self._parent_class, self._target)
  32        """The target object to plot. Default is mysmashmodel"""
  33
  34    @property
  35    def target(self):
  36        """Property: The target object to plot. Default is mysmashmodel"""
  37        return self._target
  38
  39    @target.setter
  40    def target(self, target):
  41        """Setter: The target object to plot. Default is mysmashmodel"""
  42        valid_target = [
  43            "mymesh",
  44            "mysmashmodel",
  45            "optimize_model",
  46            "validation_model",
  47            "warmup_model",
  48        ]
  49
  50        if target in valid_target:
  51            self._target = target
  52        else:
  53            raise ValueError(
  54                f"The target {target} is not valid. Choice are {valid_target}"
  55            )
  56            return
  57
  58        self._plot_object = getattr(self._parent_class, target)
  59
  60    def plot_mesh(
  61        self,
  62        coef_hydro: float = 99.0,
  63        ax_settings: dict = {},
  64        fig_settings: dict = {},
  65        html_show: bool = False,
  66    ):
  67        """
  68        Plot the map of the mesh of the Smash model with teh outlets and the hydrographic
  69        network.
  70        :param coef_hydro: couloring cells where the surface is higher than `coef_hydro`%
  71         of the total surface catchment, defaults to 99.0
  72        :type coef_hydro: float, optional
  73        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
  74         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  75        :type ax_settings: dict, optional
  76        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
  77         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  78        :type fig_settings: dict, optional
  79        :param html_show: Display the figure in an html page with your navigator, defaults
  80         to False
  81        :type html_show: bool, optional
  82
  83        """
  84        default_ax_settings = plot.ax_properties(
  85            title="Mesh of the Smash model",
  86            xlabel="x_coords",
  87            ylabel="y_coords",
  88        )
  89        default_ax_settings.update(**ax_settings)
  90
  91        fig_settings = plot.fig_properties(**fig_settings)
  92
  93        if not hasattr(self._parent_class.mymesh, "mesh"):
  94            raise ValueError("No smash mesh found. Build the mesh first.")
  95
  96        fig, ax = plot.plot_mesh(
  97            self._parent_class.mymesh.mesh,
  98            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
  99            coef_hydro=coef_hydro,
 100            ax_settings=ax_settings,
 101            fig_settings=fig_settings,
 102        )
 103
 104        if fig_settings.figname is None:
 105            if tools.with_reticulate() or html_show:
 106                mpld3.show(fig, open_browser=True)
 107            else:
 108                fig.show()
 109
 110    def plot_catchment_surface_consistency(
 111        self,
 112        label: bool = True,
 113        ax_settings: dict = {},
 114        fig_settings: dict = {},
 115        plot_settings: dict = {},
 116        html_show: bool = False,
 117    ):
 118        """
 119        Plot the modeled surface vs the observed surface. Check its consistency.
 120         :param label, labels the point on the plot with the code of the outlets.
 121         :type label: bool, default True
 122        :param ax_settings, any properties of plot.ax_properties() class can be defined
 123         in this dictionnary, defaults to {}
 124        :type ax_settings: dict, optional
 125        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 126         plot.fig_properties() class can be defined in this dictionnary, defaults to {}
 127        :type fig_settings: dict, optional
 128        :param plot_settings,  any properties of plot.plot_properties() class can be
 129        defined in this dictionnary, defaults to {}
 130        :param html_show: Display the figure in an html page with your navigator, defaults
 131         to False
 132        :type html_show: bool, optional
 133
 134        """
 135
 136        default_ax_settings = plot.ax_properties(
 137            title="Modeled and observed surface consistency",
 138            xlabel="Observed surface",
 139            ylabel="Modeled surface",
 140        )
 141        default_ax_settings.update(**ax_settings)
 142
 143        fig_settings = plot.fig_properties(**fig_settings)
 144
 145        if not hasattr(self._parent_class.mymesh, "mesh"):
 146            raise ValueError("No smash mesh found. Build the mesh first.")
 147
 148        fig, ax = plot.plot_catchment_surface_consistency(
 149            mesh=self._parent_class.mymesh.mesh,
 150            label=label,
 151            ax_settings=ax_settings,
 152            fig_settings=fig_settings,
 153            plot_settings=plot_settings,
 154        )
 155
 156        if fig_settings.figname is None:
 157            if tools.with_reticulate() or html_show:
 158                mpld3.show(fig, open_browser=True)
 159            else:
 160                fig.show()
 161
 162    def plot_catchment_surface_error(
 163        self,
 164        ax_settings: dict = {},
 165        fig_settings: dict = {},
 166        html_show: bool = False,
 167    ):
 168        """
 169        Plot the modeled surface vs the observed surface. Check its consistency.
 170         :param ax_settings, any properties of plot.ax_properties() class can be defined
 171         in this dictionnary, defaults to {}
 172        :type ax_settings: dict, optional
 173        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 174         plot.fig_properties() class can be defined in this dictionnary, defaults to {}
 175        :param html_show: Display the figure in an html page with your navigator, defaults
 176         to False
 177        :type html_show: bool, optional
 178
 179        """
 180
 181        default_ax_settings = plot.ax_properties(
 182            title="Catchment surface error",
 183            xlabel="Catchments",
 184            ylabel="(Ssim - Sobs)/Sobs",
 185        )
 186        default_ax_settings.update(**ax_settings)
 187
 188        fig_settings = plot.fig_properties(**fig_settings)
 189
 190        if not hasattr(self._parent_class.mymesh, "mesh"):
 191            raise ValueError("No smash mesh found. Build the mesh first.")
 192
 193        fig, ax = plot.plot_catchment_surface_error(
 194            mesh=self._parent_class.mymesh.mesh,
 195            ax_settings=ax_settings,
 196            fig_settings=fig_settings,
 197        )
 198
 199        if fig_settings.figname is None:
 200            if tools.with_reticulate() or html_show:
 201                mpld3.show(fig, open_browser=True)
 202            else:
 203                fig.show()
 204
 205    @tools.autocast_args
 206    def plot_xy_quantile(
 207        self,
 208        duration: int = 1,
 209        X: int = 0,
 210        Y: int = 0,
 211        ax_settings: dict = {},
 212        fig_settings: dict = {},
 213        plot_settings: dict = {},
 214        html_show: bool = False,
 215    ):
 216        """
 217
 218        :param duration: Duration of the quantile, defaults to 1
 219        :type duration: int, optional
 220        :param X: X coordinate of the targeted cell (matrix coordinate system), defaults
 221         to 0
 222        :type X: int, optional
 223        :param Y: Y coordinate of the targeted cell (matrix coordinate system), defaults
 224        to 0
 225        :type Y: int, optional
 226        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 227         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 228        :type ax_settings: dict, optional
 229        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 230        plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 231        :type fig_settings: dict, optional
 232        :param html_show: Display the figure in an html page with your navigator,
 233         defaults to False
 234        :type html_show: bool, optional
 235
 236        """
 237
 238        if not hasattr(
 239            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 240        ):
 241            raise ValueError(
 242                f"No statistical results found for duration {duration}h"
 243            )
 244
 245        results_quantile = getattr(
 246            self._plot_object.mystats.quantile_stats,
 247            f"Quantile_{duration}h",
 248        )
 249
 250        if self._plot_object.smash.mesh.active_cell[X, Y] == 0:
 251            raise ValueError(
 252                f"`{X},{Y}` coordinates does not correspond to an active cell."
 253            )
 254
 255        default_ax_settings = plot.ax_properties(
 256            title=f"Maximal discharges frequency curve on {results_quantile.chunk_size}"
 257            " days",
 258            xscale="log",
 259            xlabel=f"Return period (*{results_quantile.chunk_size} days)",
 260            ylabel="Discharges (m³/s)",
 261            grid=True,
 262            legend=True,
 263        )
 264        default_ax_settings.update(**ax_settings)
 265
 266        fig_settings = plot.fig_properties(**fig_settings)
 267
 268        fig, ax = plot.plot_xy_quantile(
 269            results_quantile.__dict__,
 270            X,
 271            Y,
 272            ax_settings=default_ax_settings,
 273            fig_settings=fig_settings,
 274            plot_settings=plot_settings,
 275        )
 276
 277        if fig_settings.figname is None:
 278            if tools.with_reticulate() or html_show:
 279                mpld3.show(fig, open_browser=True)
 280            else:
 281                fig.show()
 282        # return fig, ax
 283
 284    @tools.autocast_args
 285    def plot_outlets_quantile(
 286        self,
 287        duration: int = 1,
 288        quantile_obs=True,
 289        gauge: list | None = None,
 290        ax_settings: dict = {},
 291        fig_settings: dict = {},
 292        plot_settings: dict = {},
 293        html_show: bool = False,
 294    ):
 295        """
 296        Plot the quantiles prediction for different return period for every outlets.
 297        :param duration: Duration of the quantile, defaults to 1
 298        :type duration: int, optional
 299        :param quantile_obs: Compute and display the observed quantile in th graphics.
 300        Observed quantile are computed again the whole observed discharge chronicle
 301        from 1900 until today.
 302        :type quantile_obs: Bool, default is True
 303        :param gauge: List of gauge code to plot. Default is None. If None all gague
 304        are plotted
 305        :type gauge: list | None, default None.
 306        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 307         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 308        :type ax_settings: dict, optional
 309        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 310         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 311        :type fig_settings: dict, optional
 312        :param plot_settings: Parameters of the matplotlib figure 'fig'. Any properties of
 313         plot.plot_settings() class ca be defined in this dictionnary, defaults to {}
 314        :type plot_settings: dict, optional
 315        :param html_show: Display the figure in an html page with your navigator, defaults
 316        to False
 317        :type html_show: bool, optional
 318
 319        """
 320
 321        # fig_settings = plot.fig_properties(**fig_settings)
 322
 323        if not hasattr(
 324            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 325        ):
 326            raise ValueError(
 327                f"No statistical results found for duration {duration}h"
 328            )
 329
 330        gauge_pos = list(self._plot_object.smash.mesh.gauge_pos)
 331        gauge_code = list(self._plot_object.smash.mesh.code)
 332
 333        if gauge is not None:
 334            list_ind_gauge = []
 335            for i, g in enumerate(gauge_code):
 336                if g in gauge:
 337                    list_ind_gauge.append(i)
 338                else:
 339                    print(
 340                        f"</> gauge {g} not found in the mesh gauge list {gauge_code}"
 341                    )
 342            if len(list_ind_gauge) > 0:
 343                gauge_pos = gauge_pos[list_ind_gauge]
 344                gauge_code = gauge_code[list_ind_gauge]
 345            else:
 346                print(
 347                    f"</> gauge {gauge} not found in the mesh gauge list {gauge_code}"
 348                )
 349
 350        yfig = int(np.sqrt(len(gauge_pos)))
 351        xfig = int(np.ceil(len(gauge_pos) / yfig))
 352
 353        default_fig_settings = plot.fig_properties(
 354            ysize=yfig * 5, xsize=xfig * 3
 355        )
 356        default_fig_settings.update(**fig_settings)
 357
 358        if quantile_obs:
 359            res_quantile_obs = stats.quantil_obs(
 360                qobs_directory=self._plot_object.smash.setup.qobs_directory,
 361                code=gauge_code,
 362                model_time_step=self._plot_object.smash.setup.dt,
 363                quantile_duration=duration,
 364            )
 365        else:
 366            res_quantile_obs = None
 367
 368        fig, axs = plt.subplots(
 369            xfig,
 370            yfig,
 371            constrained_layout=True,
 372        )
 373
 374        for ax, coords, code in zip(axs.flat, gauge_pos, gauge_code):
 375
 376            X, Y = coords
 377            results_quantile = getattr(
 378                self._plot_object.mystats.quantile_stats,
 379                f"Quantile_{duration}h",
 380            )
 381
 382            # default_ax_settings = plot.ax_properties(
 383            #     title=f"Discharges quantile at gauge {code}",
 384            #     legend_fontsize=6,
 385            # )
 386            # default_ax_settings.update(**ax_settings)
 387
 388            default_ax_settings = plot.ax_properties(
 389                title=f"Discharges quantile at gauge {code}",
 390                xscale="log",
 391                xlabel=f"Return period (*{results_quantile.chunk_size} days)",
 392                ylabel="Discharges (m³/s)",
 393                grid=True,
 394                legend=True,
 395                legend_fontsize=8,
 396                xtics_fontsize=8,
 397                ytics_fontsize=8,
 398            )
 399            default_ax_settings.update(**ax_settings)
 400
 401            default_plot_settings = plot.plot_properties(
 402                markersize=6,
 403            )
 404            default_plot_settings.update(**plot_settings)
 405
 406            fig, ax = plot.plot_xy_quantile(
 407                results_quantile.__dict__,
 408                X,
 409                Y,
 410                res_quantile_obs=res_quantile_obs,
 411                gauge_pos=list(gauge_code).index(code),
 412                figure=[fig, ax],
 413                ax_settings=default_ax_settings,
 414                plot_settings=default_plot_settings,
 415            )
 416
 417        default_fig_settings.change((fig, axs))
 418
 419        if default_fig_settings.figname is None:
 420            if tools.with_reticulate() or html_show:
 421                mpld3.show(fig, open_browser=True)
 422            else:
 423                fig.show()
 424
 425        # return fig, axs
 426
 427    @tools.autocast_args
 428    def plot_spatial_quantile(
 429        self,
 430        duration: int = 1,
 431        T: int = 2,
 432        vmin: float | None = 0,
 433        vmax: float | None = None,
 434        ax_settings: dict = {},
 435        fig_settings: dict = {},
 436        html_show=False,
 437    ):
 438        """
 439        Plot the map of the quantiles for given return period and a given duration.
 440        :param duration: Duration of the quantile, defaults to 1
 441        :type duration: int, optional
 442        :param T: return period, defaults to 2 (default is years, but that depends
 443         of the chunk size)
 444        :type T: int, optional
 445        :param vmin: Minimal bounds value for the colorbar, defaults to 0
 446        :type vmin: float, optional
 447        :param vmax: Maximal bounds value for the colorbar, defaults to None
 448        :type vmax: float, optional
 449        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 450         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 451        :type ax_settings: dict, optional
 452        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 453         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 454        :type fig_settings: dict, optional
 455        :param html_show: Display the figure in an html page with your navigator, defaults to False
 456        :type html_show: bool, optional
 457
 458        """
 459
 460        fig_settings = plot.fig_properties(**fig_settings)
 461
 462        if not hasattr(
 463            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 464        ):
 465            raise ValueError(
 466                f"No statistical results found for duration {duration}h"
 467            )
 468
 469        results_quantile = getattr(
 470            self._plot_object.mystats.quantile_stats,
 471            f"Quantile_{duration}h",
 472        )
 473
 474        default_ax_settings = plot.ax_properties(
 475            title=f"Discharges quantile for duration={duration} h, T={T}",
 476            xlabel="Coords X",
 477            ylabel="Coords_Y",
 478            clabel="Discharge (m^3/s)",
 479            cmap="viridis",
 480        )
 481        default_ax_settings.update(**ax_settings)
 482
 483        z = list(results_quantile.T).index(T)
 484
 485        fig, ax = plot.plot_image(
 486            matrice=results_quantile.Q_th[:, :, z],
 487            bbox=geo_toolbox.get_bbox_from_smash_mesh(
 488                self._parent_class.mymesh.mesh
 489            ),
 490            vmin=vmin,
 491            vmax=vmax,
 492            mask=self._plot_object.smash.mesh.active_cell,
 493            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
 494            ax_settings=default_ax_settings,
 495            fig_settings=fig_settings,
 496        )
 497
 498        if fig_settings.figname is None:
 499            if tools.with_reticulate() or html_show:
 500                mpld3.show(fig, open_browser=True)
 501            else:
 502                fig.show()
 503
 504        # return fig, ax
 505
 506    @tools.autocast_args
 507    def multiplot_spatial_quantile(
 508        self,
 509        duration: int = 1,
 510        vmin: float | None = 0,
 511        vmax: float | None = None,
 512        ax_settings={},
 513        fig_settings={},
 514        html_show: bool = False,
 515    ):
 516        """
 517        Plot the map of the quantiles for every return period for a given duration.
 518        :param duration: Duration of the quantile, defaults to 1
 519        :type duration: int, optional
 520        :param vmin: Minimal bounds value for the colorbar, defaults to 0
 521        :type vmin: float, optional
 522        :param vmax: Maximal bounds value for the colorbar, defaults to None
 523        :type vmax: float, optional
 524        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 525         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 526        :type ax_settings: dict, optional
 527        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 528         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 529        :type fig_settings: dict, optional
 530        :param html_show: Display the figure in an html page with your navigator, defaults
 531         to False
 532        :type html_show: bool, optional
 533
 534        """
 535
 536        fig_settings = plot.fig_properties(**fig_settings)
 537
 538        if not hasattr(
 539            self._plot_object.mystats.quantile_stats, f"Quantile_{duration}h"
 540        ):
 541            raise ValueError(
 542                f"No statistical results found for duration {duration}h"
 543            )
 544
 545        results_quantile = getattr(
 546            self._plot_object.mystats.quantile_stats,
 547            f"Quantile_{duration}h",
 548        )
 549
 550        yfig = int(np.sqrt(len(results_quantile.T)))
 551        xfig = int(np.ceil(len(results_quantile.T) / yfig))
 552
 553        fig, axs = plt.subplots(
 554            xfig,
 555            yfig,
 556            constrained_layout=False,
 557        )
 558        plt.subplots_adjust(
 559            left=None,
 560            bottom=None,
 561            right=None,
 562            top=None,
 563            wspace=0.5,
 564            hspace=None,
 565        )
 566
 567        for ax, T in zip(axs.flat, results_quantile.T):
 568
 569            default_ax_settings = plot.ax_properties(
 570                title=f"Discharges quantile for duration={duration} h, T={T}",
 571                xlabel="Coords X",
 572                ylabel="Coords_Y",
 573                clabel="Discharge (m^3/s)",
 574                cmap="viridis",
 575                title_fontsize=10,
 576                label_fontsize=8,
 577                xtics_fontsize=6,
 578                ytics_fontsize=6,
 579            )
 580            default_ax_settings.update(**ax_settings)
 581
 582            z = list(results_quantile.T).index(T)
 583
 584            fig, ax = plot.plot_image(
 585                matrice=results_quantile.Q_th[:, :, z],
 586                bbox=geo_toolbox.get_bbox_from_smash_mesh(
 587                    self._parent_class.mymesh.mesh
 588                ),
 589                vmin=vmin,
 590                vmax=vmax,
 591                mask=self._plot_object.smash.mesh.active_cell,
 592                catchment_polygon=self._parent_class.mymesh.catchment_polygon,
 593                ax_settings=default_ax_settings,
 594                figure=[fig, ax],
 595            )
 596
 597        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
 598        fig_settings.change((fig, axs))
 599
 600        if fig_settings.figname is None or html_show:
 601            if tools.with_reticulate():
 602                mpld3.show(fig, open_browser=True)
 603            else:
 604                fig.show()
 605
 606        # return fig, axs
 607
 608    def plot_spatial_stats(
 609        self,
 610        stats: str = "max",
 611        vmin: float | None = 0,
 612        vmax: float | None = None,
 613        ax_settings: dict = {},
 614        fig_settings: dict = {},
 615        html_show: bool = False,
 616    ):
 617        """
 618        Plot the map of a given spatial statistic.
 619        :param stats: The statistic to plot, choice are
 620         'max, min, mean, median, q20, q80', defaults to "max"
 621        :type stats: str, optional
 622        ::param vmin: Minimal bounds value for the colorbar, defaults to 0
 623        :type vmin: float, optional
 624        :param vmax: Maximal bounds value for the colorbar, defaults to None
 625        :type vmax: float, optional
 626        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 627         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 628        :type ax_settings: dict, optional
 629        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 630         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 631        :type fig_settings: dict, optional
 632        :param html_show: Display the figure in an html page with your navigator, defaults
 633         to False
 634        :type html_show: bool, optional
 635
 636        """
 637
 638        fig_settings = plot.fig_properties(**fig_settings)
 639
 640        if not hasattr(self._plot_object.mystats.spatial_stats.results, stats):
 641            raise ValueError(
 642                f"Statistical results `{stats}` not found. Choice are: "
 643                "[min, max, mean, median, q20, q80]"
 644            )
 645
 646        stats_matrix = getattr(
 647            self._plot_object.mystats.spatial_stats.results,
 648            stats,
 649        )
 650        default_ax_settings = plot.ax_properties(
 651            title="Maximal Discharges on periode"
 652            f" {self._plot_object.smash.setup.start_time} -"
 653            f" {self._plot_object.smash.setup.end_time}",
 654            xlabel="Coords X",
 655            ylabel="Coords_Y",
 656            clabel="Discharge (m^3/s)",
 657            cmap="viridis",
 658        )
 659        default_ax_settings.update(**ax_settings)
 660
 661        fig, ax = plot.plot_image(
 662            matrice=stats_matrix,
 663            bbox=geo_toolbox.get_bbox_from_smash_mesh(
 664                self._parent_class.mymesh.mesh
 665            ),
 666            vmin=vmin,
 667            vmax=vmax,
 668            mask=self._plot_object.smash.mesh.active_cell,
 669            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
 670            ax_settings=default_ax_settings,
 671            fig_settings=fig_settings,
 672        )
 673
 674        if fig_settings.figname is None:
 675            if tools.with_reticulate() or html_show:
 676                mpld3.show(fig, open_browser=True)
 677            else:
 678                fig.show()
 679
 680        # return fig, ax
 681
 682    def plot_hydrograph(
 683        self,
 684        columns: list | None = [],
 685        outlets_name: list = [],
 686        plot_rainfall: bool = True,
 687        ax_settings: dict = {},
 688        fig_settings: dict = {},
 689        plot_settings_sim: dict = {},
 690        plot_settings_obs: dict = {},
 691        html_show: bool = False,
 692    ):
 693        """
 694        Plot the simulated and the observed hydrogram for different outlets.
 695
 696        :param columns: Columns of the matrix to plot (outlets), defaults to []
 697        :type columns: list | None, optional
 698        :param outlets_name: List of the outlets name to plot, defaults to []
 699        :type outlets_name: list, optional
 700        :param plot_rainfall: Plot the rainfall on the graphics, defaults to True
 701        :type plot_rainfall: bool, optional
 702        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 703         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 704        :type ax_settings: dict, optional
 705        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 706         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 707        :type fig_settings: dict, optional
 708        :param plot_settings_sim: Parameters of the matplotlib curves. Any propoerties of
 709         plot.plot_properties() class ca be defined in this dictionnary, defaults to {}
 710        :type plot_settings_sim: dict, optional
 711        :param plot_settings_obs: DParameters of the matplotlib curves. Any propoerties of
 712         plot.plot_properties() class ca be defined in this dictionnary, defaults to {}
 713        :type plot_settings_obs: dict, optional
 714        :pparam html_show: Display the figure in an html page with your navigator, defaults
 715         to False
 716        :type html_show: bool, optional
 717
 718        """
 719
 720        fig_settings = plot.fig_properties(**fig_settings)
 721
 722        if len(outlets_name) > 0:
 723            columns = tools.array_isin(
 724                self._plot_object.smash.mesh.code,
 725                np.array(outlets_name),
 726            )
 727        elif len(columns) > 0:
 728            outlets_name = [
 729                self._plot_object.smash.mesh.code[i] for i in columns
 730            ]
 731
 732        if columns is None:
 733            columns = list(
 734                range(0, self._plot_object.smash.response.q.shape[0])
 735            )
 736            outlets_name = list(self._plot_object.smash.mesh.code)
 737
 738        if len(columns) == 0:
 739            columns = [0]
 740            outlets_name = [list(self._plot_object.smash.mesh.code)[0]]
 741
 742        fig, ax = plot.plot_hydrograph(
 743            model=self._plot_object.smash,
 744            columns=columns,
 745            outlets_name=outlets_name,
 746            plot_rainfall=plot_rainfall,
 747            ax_settings=ax_settings,
 748            fig_settings=fig_settings,
 749            plot_settings_sim=plot_settings_sim,
 750            plot_settings_obs=plot_settings_obs,
 751        )
 752
 753        if fig_settings.figname is None:
 754            if tools.with_reticulate() or html_show:
 755                mpld3.show(fig, open_browser=True)
 756            else:
 757                fig.show()
 758
 759        # return fig, ax
 760
 761    def plot_misfit(
 762        self,
 763        columns: list | None = None,
 764        outlets_name: list = [],
 765        misfit: str = "nse",
 766        ax_settings: dict = {},
 767        fig_settings: dict = {},
 768        html_show: bool = False,
 769    ):
 770        """
 771        Plot a misfit criteria for a given list of outlet.
 772        :param columns: Columns of the matrix to plot (outlets), defaults to []
 773        :type columns: list | None, optional
 774        :param outlets_name: List of the outlets name to plot, defaults to []
 775        :type outlets_name: list, optional
 776        :param misfit: The misfit criteria to plot, choice are
 777        "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
 778        :type misfit: str, optional
 779        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 780         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 781        :type ax_settings: dict, optional
 782        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 783         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 784        :type fig_settings: dict, optional
 785        :param html_show: Display the figure in an html page with your navigator, defaults
 786         to False
 787        :type html_show: bool, optional
 788
 789        """
 790
 791        fig_settings = plot.fig_properties(**fig_settings)
 792
 793        values = getattr(
 794            self._plot_object.mystats.misfit_stats.results, misfit
 795        )
 796
 797        if len(outlets_name) > 0:
 798            columns = tools.array_isin(
 799                self._plot_object.smash.mesh.code,
 800                np.array(outlets_name),
 801            )
 802
 803        if columns is None:
 804            columns = list(
 805                range(0, self._plot_object.smash.response.q.shape[0])
 806            )
 807            outlets_name = self._plot_object.smash.mesh.code
 808
 809        fig, ax = plot.plot_misfit(
 810            values=values[columns],
 811            names=outlets_name,
 812            columns=None,
 813            misfit=misfit,
 814            ax_settings=ax_settings,
 815            fig_settings=fig_settings,
 816        )
 817
 818        if fig_settings.figname is None:
 819            if tools.with_reticulate() or html_show:
 820                mpld3.show(fig, open_browser=True)
 821            else:
 822                fig.show()
 823
 824        # return fig, ax
 825
 826    def plot_outlet_stats(
 827        self,
 828        columns: list | None = None,
 829        outlets_name: list = [],
 830        stat: str = "max",
 831        ax_settings: dict = {},
 832        fig_settings: dict = {},
 833        html_show: bool = False,
 834    ):
 835        """
 836        Plot a statistical criteria for a given list of outlet.
 837        :param columns: Columns of the matrix to plot (outlets), defaults to []
 838        :type columns: list | None, optional
 839        :param outlets_name: List of the outlets name to plot, defaults to []
 840        :type outlets_name: list, optional
 841        :param misfit: The misfit criteria to plot, choice are
 842        "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
 843        :type misfit: str, optional
 844        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 845         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 846        :type ax_settings: dict, optional
 847        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 848         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 849        :type fig_settings: dict, optional
 850        :param html_show: Display the figure in an html page with your navigator, defaults
 851         to False
 852        :type html_show: bool, optional
 853
 854        """
 855
 856        fig_settings = plot.fig_properties(**fig_settings)
 857
 858        values_sim = getattr(
 859            self._plot_object.mystats.outlets_stats.results_sim, stat
 860        )
 861        values_obs = getattr(
 862            self._plot_object.mystats.outlets_stats.results_obs, stat
 863        )
 864
 865        if len(outlets_name) > 0:
 866            columns = tools.array_isin(
 867                self._plot_object.smash.mesh.code,
 868                np.array(outlets_name),
 869            )
 870
 871        if columns is None:
 872            columns = list(
 873                range(0, self._plot_object.smash.response.q.shape[0])
 874            )
 875            outlets_name = list(self._plot_object.smash.mesh.code)
 876
 877        fig, ax = plot.plot_outlet_stats(
 878            values_sim=values_sim[columns],
 879            values_obs=values_obs[columns],
 880            names=outlets_name,
 881            columns=None,
 882            stat=stat,
 883            ax_settings=ax_settings,
 884            fig_settings=fig_settings,
 885        )
 886
 887        if fig_settings.figname is None:
 888            if tools.with_reticulate() or html_show:
 889                mpld3.show(fig, open_browser=True)
 890            else:
 891                fig.show()
 892
 893        # return fig, ax
 894
 895    def multiplot_misfit(
 896        self,
 897        columns: list | None = None,
 898        outlets_name: list = [],
 899        misfit: list = [
 900            "nse",
 901            "nnse",
 902            "kge",
 903            "mse",
 904            "rmse",
 905            "nrmse",
 906            "se",
 907            "mae",
 908            "mape",
 909            "lgrm",
 910        ],
 911        ax_settings: dict = {},
 912        fig_settings: dict = {},
 913        html_show: bool = False,
 914    ):
 915        """
 916        Plot misfit criterium for a given list of outlets.
 917
 918        :param columns: Columns of the matrix to plot (outlets), defaults to []
 919        :type columns: list | None, optional
 920        :param outlets_name: List of the outlets name to plot, defaults to []
 921        :type outlets_name: list, optional
 922        :param misfit: The misfit criteria to plot, list of criteria among
 923        "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
 924        :type misfit: str, optional
 925        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 926         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 927        :type ax_settings: dict, optional
 928        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 929         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 930        :type fig_settings: dict, optional
 931        :param html_show: Display the figure in an html page with your navigator, defaults
 932         to False
 933        :type html_show: bool, optional
 934
 935        """
 936
 937        fig_settings = plot.fig_properties(**fig_settings)
 938
 939        if len(outlets_name) > 0:
 940            columns = tools.array_isin(
 941                self._plot_object.smash.mesh.code,
 942                np.array(outlets_name),
 943            )
 944
 945        if columns is None:
 946            columns = list(
 947                range(0, self._plot_object.smash.response.q.shape[0])
 948            )
 949            outlets_name = list(self._plot_object.smash.mesh.code)
 950
 951        yfig = int(np.sqrt(len(misfit)))
 952        xfig = int(np.ceil(len(misfit) / yfig))
 953
 954        fig, axs = plt.subplots(
 955            xfig,
 956            yfig,
 957            constrained_layout=True,
 958        )
 959
 960        # for ax in axs:
 961        #     ax.set_axis_off()
 962
 963        for ax, crit in zip(
 964            axs.flat,
 965            misfit,
 966        ):
 967
 968            # ax.set_axis_on()
 969            ax_settings["ylabel"] = f"{crit} criteria"
 970            ax_settings["title"] = f"{crit} criteria"
 971
 972            if hasattr(self._plot_object.mystats.misfit_stats.results, crit):
 973                values = getattr(
 974                    self._plot_object.mystats.misfit_stats.results, crit
 975                )
 976            else:
 977                raise ValueError(
 978                    f"`{crit}` is not a valid statistic. choice are:"
 979                    "[nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge]"
 980                )
 981
 982            fig, ax = plot.plot_misfit(
 983                values=values[columns],
 984                names=np.array(outlets_name),
 985                columns=None,
 986                misfit=crit,
 987                figure=(fig, ax),
 988                ax_settings=ax_settings,
 989            )
 990
 991        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
 992        fig_settings.change((fig, ax))
 993
 994        if fig_settings.figname is None:
 995            if tools.with_reticulate() or html_show:
 996                mpld3.show(fig, open_browser=True)
 997            else:
 998                fig.show()
 999
1000        # return fig, ax
1001
1002    def plot_misfit_map(
1003        self,
1004        misfit: str = "nse",
1005        coef_hydro: float = 99.0,
1006        ax_settings: dict = {},
1007        fig_settings: dict = {},
1008        plot_settings: dict = {},
1009        html_show: bool = False,
1010    ):
1011        """
1012        Plot a map of a misfit criteria.
1013
1014        :param columns: Columns of the matrix to plot (outlets), defaults to []
1015        :type columns: list | None, optional
1016        :param outlets_name: List of the outlets name to plot, defaults to []
1017        :type outlets_name: list, optional
1018        :param misfit: The misfit criteria to plot, choice are
1019        "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
1020        :type misfit: str, optional
1021        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1022         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1023        :type ax_settings: dict, optional
1024        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1025         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1026        :type fig_settings: dict, optional
1027        :param html_show: Display the figure in an html page with your navigator, defaults
1028         to False
1029        :type html_show: bool, optional
1030
1031        """
1032
1033        if hasattr(self._plot_object.mystats.misfit_stats.results, misfit):
1034            values = getattr(
1035                self._plot_object.mystats.misfit_stats.results, misfit
1036            )
1037        else:
1038            raise ValueError(
1039                f"`{misfit}` is not a valid statistic. choice are:"
1040                "[nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge]"
1041            )
1042
1043        fig_settings = plot.fig_properties(**fig_settings)
1044
1045        name = self._plot_object.smash.mesh.code
1046        mesh = self._parent_class.mymesh.mesh
1047
1048        fig, ax = plot.plot_misfit_map(
1049            values=values,
1050            names=name,
1051            mesh=mesh,
1052            misfit=misfit,
1053            coef_hydro=coef_hydro,
1054            ax_settings=ax_settings,
1055            fig_settings=fig_settings,
1056            plot_settings=plot_settings,
1057        )
1058
1059        if fig_settings.figname is None:
1060            if tools.with_reticulate() or html_show:
1061                mpld3.show(fig, open_browser=True)
1062            else:
1063                fig.show()
1064
1065        # return fig, ax
1066
1067    def multiplot_parameters(
1068        self,
1069        mask_active_cell=False,
1070        ax_settings={},
1071        fig_settings={},
1072        html_show: bool = False,
1073    ):
1074        """
1075        Multiplot map of every Smash parameters
1076        :param mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
1077        :type mask_active_cell: bool, False, optional
1078        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1079         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1080        :type ax_settings: dict, optional
1081        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1082         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1083        :type fig_settings: dict, optional
1084        :param html_show: Display the figure in an html page with your navigator, defaults
1085         to False
1086        :type html_show: bool, optional
1087
1088        """
1089
1090        default_fig_settings = plot.fig_properties(xsize=8, ysize=8)
1091        default_fig_settings.update(**fig_settings)
1092
1093        param = list(self._plot_object.smash.rr_parameters.keys)
1094
1095        if mask_active_cell:
1096            mask = self._plot_object.smash.mesh.active_cell
1097        else:
1098            mask = None
1099
1100        yfig = int(np.sqrt(len(param)))
1101        xfig = int(np.ceil(len(param) / yfig))
1102
1103        fig, axs = plt.subplots(
1104            xfig,
1105            yfig,
1106            constrained_layout=False,
1107        )
1108        plt.subplots_adjust(
1109            left=None,
1110            bottom=None,
1111            right=None,
1112            top=None,
1113            wspace=0.5,
1114            hspace=0.5,
1115        )
1116        for ax, p in zip(axs.flat, param):
1117
1118            default_ax_settings = plot.ax_properties(
1119                title=f"{p} parameters map",
1120                xlabel="Coords X",
1121                ylabel="Coords_Y",
1122                clabel=f"{p} parameter value",
1123                cmap="viridis",
1124            )
1125            default_ax_settings.update(**ax_settings)
1126
1127            z = param.index(p)
1128
1129            fig, ax = plot.plot_image(
1130                matrice=self._plot_object.smash.rr_parameters.values[:, :, z],
1131                bbox=geo_toolbox.get_bbox_from_smash_mesh(
1132                    self._parent_class.mymesh.mesh
1133                ),
1134                mask=mask,
1135                vmin=0.0,
1136                catchment_polygon=self._parent_class.mymesh.catchment_polygon,
1137                ax_settings=default_ax_settings,
1138                figure=[fig, ax],
1139            )
1140
1141        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
1142        default_fig_settings.change((fig, axs))
1143
1144        if default_fig_settings.figname is None or html_show:
1145            if tools.with_reticulate():
1146                mpld3.show(fig, open_browser=True)
1147            else:
1148                fig.show()
1149
1150        # return fig, axs
1151
1152    def plot_parameters(
1153        self,
1154        param="cp",
1155        mask_active_cell=False,
1156        vmin=0.0,
1157        vmax=None,
1158        ax_settings={},
1159        fig_settings={},
1160        html_show: bool = False,
1161    ):
1162        """
1163        Plot a map of a Smash parameters
1164        :param param: Name of the parameter to plot, defaults to "cp"
1165        :type param: str, optional
1166        :param mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
1167        :type mask_active_cell: bool, False, optional
1168        :param vmin: Minimum value of the colorbar, defaults to 0.0
1169        :type vmin: float, optional
1170        :param vmax: Maximum value of the colorbar, defaults to None
1171        :type vmax: float, optional
1172        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1173         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1174        :type ax_settings: dict, optional
1175        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1176         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1177        :type fig_settings: dict, optional
1178        :param html_show: Display the figure in an html page with your navigator, defaults
1179         to False
1180        :type html_show: bool, optional
1181        """
1182
1183        fig_settings = plot.fig_properties(**fig_settings)
1184
1185        list_param = list(self._plot_object.smash.rr_parameters.keys)
1186        z = list_param.index(param)
1187
1188        if mask_active_cell:
1189            mask = self._plot_object.smash.mesh.active_cell
1190        else:
1191            mask = None
1192
1193        fig, axs = plt.subplots()
1194
1195        default_ax_settings = plot.ax_properties(
1196            title=f"{param} parameters map",
1197            xlabel="Coords X",
1198            ylabel="Coords_Y",
1199            clabel=f"{param} parameter value",
1200            cmap="viridis",
1201        )
1202        default_ax_settings.update(**ax_settings)
1203
1204        fig, ax = plot.plot_image(
1205            matrice=self._plot_object.smash.rr_parameters.values[:, :, z],
1206            bbox=geo_toolbox.get_bbox_from_smash_mesh(
1207                self._parent_class.mymesh.mesh
1208            ),
1209            mask=mask,
1210            vmin=vmin,
1211            vmax=vmax,
1212            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
1213            ax_settings=default_ax_settings,
1214        )
1215
1216        fig_settings.change((fig, axs))
1217
1218        if fig_settings.figname is None or html_show:
1219            if tools.with_reticulate():
1220                mpld3.show(fig, open_browser=True)
1221            else:
1222                fig.show()
1223
1224        # return fig, axs

Class that provide some plotting functions. Plot can be displayed with matplolib UI or as html web page. Every plot can be saved into files.

myplot(parent_class)
18    def __init__(self, parent_class):
19        """
20        Initialisation.
21        :param parent_class: The parent class src.model.model() to be able to access to
22         the smash model
23        :type parent_class: src.model.model()
24        """
25        self._parent_class = parent_class
26        """The parent class src.model.model() to be able to access to the smash model"""
27
28        self._target = "mysmashmodel"
29        """The target to plot. Default is mysmashmodel"""
30
31        self._plot_object = getattr(self._parent_class, self._target)
32        """The target object to plot. Default is mysmashmodel"""

Initialisation.

Parameters
  • parent_class: The parent class src.model.model() to be able to access to the smash model
target
34    @property
35    def target(self):
36        """Property: The target object to plot. Default is mysmashmodel"""
37        return self._target

Property: The target object to plot. Default is mysmashmodel

def plot_mesh( self, coef_hydro: float = 99.0, ax_settings: dict = {}, fig_settings: dict = {}, html_show: bool = False):
 60    def plot_mesh(
 61        self,
 62        coef_hydro: float = 99.0,
 63        ax_settings: dict = {},
 64        fig_settings: dict = {},
 65        html_show: bool = False,
 66    ):
 67        """
 68        Plot the map of the mesh of the Smash model with teh outlets and the hydrographic
 69        network.
 70        :param coef_hydro: couloring cells where the surface is higher than `coef_hydro`%
 71         of the total surface catchment, defaults to 99.0
 72        :type coef_hydro: float, optional
 73        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 74         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 75        :type ax_settings: dict, optional
 76        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 77         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 78        :type fig_settings: dict, optional
 79        :param html_show: Display the figure in an html page with your navigator, defaults
 80         to False
 81        :type html_show: bool, optional
 82
 83        """
 84        default_ax_settings = plot.ax_properties(
 85            title="Mesh of the Smash model",
 86            xlabel="x_coords",
 87            ylabel="y_coords",
 88        )
 89        default_ax_settings.update(**ax_settings)
 90
 91        fig_settings = plot.fig_properties(**fig_settings)
 92
 93        if not hasattr(self._parent_class.mymesh, "mesh"):
 94            raise ValueError("No smash mesh found. Build the mesh first.")
 95
 96        fig, ax = plot.plot_mesh(
 97            self._parent_class.mymesh.mesh,
 98            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
 99            coef_hydro=coef_hydro,
100            ax_settings=ax_settings,
101            fig_settings=fig_settings,
102        )
103
104        if fig_settings.figname is None:
105            if tools.with_reticulate() or html_show:
106                mpld3.show(fig, open_browser=True)
107            else:
108                fig.show()

Plot the map of the mesh of the Smash model with teh outlets and the hydrographic network.

Parameters
  • coef_hydro: couloring cells where the surface is higher than coef_hydro% of the total surface catchment, defaults to 99.0
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_catchment_surface_consistency( self, label: bool = True, ax_settings: dict = {}, fig_settings: dict = {}, plot_settings: dict = {}, html_show: bool = False):
110    def plot_catchment_surface_consistency(
111        self,
112        label: bool = True,
113        ax_settings: dict = {},
114        fig_settings: dict = {},
115        plot_settings: dict = {},
116        html_show: bool = False,
117    ):
118        """
119        Plot the modeled surface vs the observed surface. Check its consistency.
120         :param label, labels the point on the plot with the code of the outlets.
121         :type label: bool, default True
122        :param ax_settings, any properties of plot.ax_properties() class can be defined
123         in this dictionnary, defaults to {}
124        :type ax_settings: dict, optional
125        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
126         plot.fig_properties() class can be defined in this dictionnary, defaults to {}
127        :type fig_settings: dict, optional
128        :param plot_settings,  any properties of plot.plot_properties() class can be
129        defined in this dictionnary, defaults to {}
130        :param html_show: Display the figure in an html page with your navigator, defaults
131         to False
132        :type html_show: bool, optional
133
134        """
135
136        default_ax_settings = plot.ax_properties(
137            title="Modeled and observed surface consistency",
138            xlabel="Observed surface",
139            ylabel="Modeled surface",
140        )
141        default_ax_settings.update(**ax_settings)
142
143        fig_settings = plot.fig_properties(**fig_settings)
144
145        if not hasattr(self._parent_class.mymesh, "mesh"):
146            raise ValueError("No smash mesh found. Build the mesh first.")
147
148        fig, ax = plot.plot_catchment_surface_consistency(
149            mesh=self._parent_class.mymesh.mesh,
150            label=label,
151            ax_settings=ax_settings,
152            fig_settings=fig_settings,
153            plot_settings=plot_settings,
154        )
155
156        if fig_settings.figname is None:
157            if tools.with_reticulate() or html_show:
158                mpld3.show(fig, open_browser=True)
159            else:
160                fig.show()

Plot the modeled surface vs the observed surface. Check its consistency. :param label, labels the point on the plot with the code of the outlets. :type label: bool, default True :param ax_settings, any properties of plot.ax_properties() class can be defined in this dictionnary, defaults to {}

Parameters
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class can be defined in this dictionnary, defaults to {} :param plot_settings, any properties of plot.plot_properties() class can be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_catchment_surface_error( self, ax_settings: dict = {}, fig_settings: dict = {}, html_show: bool = False):
162    def plot_catchment_surface_error(
163        self,
164        ax_settings: dict = {},
165        fig_settings: dict = {},
166        html_show: bool = False,
167    ):
168        """
169        Plot the modeled surface vs the observed surface. Check its consistency.
170         :param ax_settings, any properties of plot.ax_properties() class can be defined
171         in this dictionnary, defaults to {}
172        :type ax_settings: dict, optional
173        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
174         plot.fig_properties() class can be defined in this dictionnary, defaults to {}
175        :param html_show: Display the figure in an html page with your navigator, defaults
176         to False
177        :type html_show: bool, optional
178
179        """
180
181        default_ax_settings = plot.ax_properties(
182            title="Catchment surface error",
183            xlabel="Catchments",
184            ylabel="(Ssim - Sobs)/Sobs",
185        )
186        default_ax_settings.update(**ax_settings)
187
188        fig_settings = plot.fig_properties(**fig_settings)
189
190        if not hasattr(self._parent_class.mymesh, "mesh"):
191            raise ValueError("No smash mesh found. Build the mesh first.")
192
193        fig, ax = plot.plot_catchment_surface_error(
194            mesh=self._parent_class.mymesh.mesh,
195            ax_settings=ax_settings,
196            fig_settings=fig_settings,
197        )
198
199        if fig_settings.figname is None:
200            if tools.with_reticulate() or html_show:
201                mpld3.show(fig, open_browser=True)
202            else:
203                fig.show()

Plot the modeled surface vs the observed surface. Check its consistency. :param ax_settings, any properties of plot.ax_properties() class can be defined in this dictionnary, defaults to {}

Parameters
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class can be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_xy_quantile(*args, **kwargs):
 95    def wrapper(*args, **kwargs):
 96
 97        bound = sig.bind(*args, **kwargs)
 98        bound.apply_defaults()
 99
100        for name, value in bound.arguments.items():
101            if name in annotations:
102
103                target_type = annotations[name]
104
105                args_ = get_args(target_type)
106
107                if target_type is None and len(args_) == 0:
108                    args_ = (type(None),)
109                    target_type = type(None)
110
111                if not type(value) in args_:
112
113                    if len(args_) > 1 and type(None) in args_:
114
115                        converted = False
116                        for t in args_:
117
118                            if t is not type(None):
119
120                                if value is not None:
121                                    try:
122                                        print(
123                                            f"</> Warning: Arg '{name}' of type {type(value)} is being"
124                                            f" converted to {t}"
125                                        )
126                                        bound.arguments[name] = t(value)
127                                        converted = True
128                                    except:
129                                        pass
130
131                                if converted:
132                                    break
133
134                        if not converted:
135                            raise TypeError(
136                                f"</> Error: Arg '{name}' must be a type of "
137                                f" {args_}, got {value}"
138                                f" ({type(value).__name__})"
139                            )
140
141                    else:
142                        if not isinstance(value, target_type):
143                            try:
144                                print(
145                                    f"</> Warning: Arg '{name}' of type {type(value)} is being"
146                                    f" converted to {target_type}"
147                                )
148                                bound.arguments[name] = target_type(value)
149                            except Exception:
150                                raise TypeError(
151                                    f"</> Error: Arg '{name}' must be a type of "
152                                    f" {target_type.__name__}, got {value}"
153                                    f" ({type(value).__name__})"
154                                )
155
156        return func(*bound.args, **bound.kwargs)
Parameters
  • duration: Duration of the quantile, defaults to 1
  • X: X coordinate of the targeted cell (matrix coordinate system), defaults to 0
  • Y: Y coordinate of the targeted cell (matrix coordinate system), defaults to 0
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_outlets_quantile(*args, **kwargs):
 95    def wrapper(*args, **kwargs):
 96
 97        bound = sig.bind(*args, **kwargs)
 98        bound.apply_defaults()
 99
100        for name, value in bound.arguments.items():
101            if name in annotations:
102
103                target_type = annotations[name]
104
105                args_ = get_args(target_type)
106
107                if target_type is None and len(args_) == 0:
108                    args_ = (type(None),)
109                    target_type = type(None)
110
111                if not type(value) in args_:
112
113                    if len(args_) > 1 and type(None) in args_:
114
115                        converted = False
116                        for t in args_:
117
118                            if t is not type(None):
119
120                                if value is not None:
121                                    try:
122                                        print(
123                                            f"</> Warning: Arg '{name}' of type {type(value)} is being"
124                                            f" converted to {t}"
125                                        )
126                                        bound.arguments[name] = t(value)
127                                        converted = True
128                                    except:
129                                        pass
130
131                                if converted:
132                                    break
133
134                        if not converted:
135                            raise TypeError(
136                                f"</> Error: Arg '{name}' must be a type of "
137                                f" {args_}, got {value}"
138                                f" ({type(value).__name__})"
139                            )
140
141                    else:
142                        if not isinstance(value, target_type):
143                            try:
144                                print(
145                                    f"</> Warning: Arg '{name}' of type {type(value)} is being"
146                                    f" converted to {target_type}"
147                                )
148                                bound.arguments[name] = target_type(value)
149                            except Exception:
150                                raise TypeError(
151                                    f"</> Error: Arg '{name}' must be a type of "
152                                    f" {target_type.__name__}, got {value}"
153                                    f" ({type(value).__name__})"
154                                )
155
156        return func(*bound.args, **bound.kwargs)

Plot the quantiles prediction for different return period for every outlets.

Parameters
  • duration: Duration of the quantile, defaults to 1
  • quantile_obs: Compute and display the observed quantile in th graphics. Observed quantile are computed again the whole observed discharge chronicle from 1900 until today.
  • gauge: List of gauge code to plot. Default is None. If None all gague are plotted
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • plot_settings: Parameters of the matplotlib figure 'fig'. Any properties of plot.plot_settings() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_spatial_quantile(*args, **kwargs):
 95    def wrapper(*args, **kwargs):
 96
 97        bound = sig.bind(*args, **kwargs)
 98        bound.apply_defaults()
 99
100        for name, value in bound.arguments.items():
101            if name in annotations:
102
103                target_type = annotations[name]
104
105                args_ = get_args(target_type)
106
107                if target_type is None and len(args_) == 0:
108                    args_ = (type(None),)
109                    target_type = type(None)
110
111                if not type(value) in args_:
112
113                    if len(args_) > 1 and type(None) in args_:
114
115                        converted = False
116                        for t in args_:
117
118                            if t is not type(None):
119
120                                if value is not None:
121                                    try:
122                                        print(
123                                            f"</> Warning: Arg '{name}' of type {type(value)} is being"
124                                            f" converted to {t}"
125                                        )
126                                        bound.arguments[name] = t(value)
127                                        converted = True
128                                    except:
129                                        pass
130
131                                if converted:
132                                    break
133
134                        if not converted:
135                            raise TypeError(
136                                f"</> Error: Arg '{name}' must be a type of "
137                                f" {args_}, got {value}"
138                                f" ({type(value).__name__})"
139                            )
140
141                    else:
142                        if not isinstance(value, target_type):
143                            try:
144                                print(
145                                    f"</> Warning: Arg '{name}' of type {type(value)} is being"
146                                    f" converted to {target_type}"
147                                )
148                                bound.arguments[name] = target_type(value)
149                            except Exception:
150                                raise TypeError(
151                                    f"</> Error: Arg '{name}' must be a type of "
152                                    f" {target_type.__name__}, got {value}"
153                                    f" ({type(value).__name__})"
154                                )
155
156        return func(*bound.args, **bound.kwargs)

Plot the map of the quantiles for given return period and a given duration.

Parameters
  • duration: Duration of the quantile, defaults to 1
  • T: return period, defaults to 2 (default is years, but that depends of the chunk size)
  • vmin: Minimal bounds value for the colorbar, defaults to 0
  • vmax: Maximal bounds value for the colorbar, defaults to None
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def multiplot_spatial_quantile(*args, **kwargs):
 95    def wrapper(*args, **kwargs):
 96
 97        bound = sig.bind(*args, **kwargs)
 98        bound.apply_defaults()
 99
100        for name, value in bound.arguments.items():
101            if name in annotations:
102
103                target_type = annotations[name]
104
105                args_ = get_args(target_type)
106
107                if target_type is None and len(args_) == 0:
108                    args_ = (type(None),)
109                    target_type = type(None)
110
111                if not type(value) in args_:
112
113                    if len(args_) > 1 and type(None) in args_:
114
115                        converted = False
116                        for t in args_:
117
118                            if t is not type(None):
119
120                                if value is not None:
121                                    try:
122                                        print(
123                                            f"</> Warning: Arg '{name}' of type {type(value)} is being"
124                                            f" converted to {t}"
125                                        )
126                                        bound.arguments[name] = t(value)
127                                        converted = True
128                                    except:
129                                        pass
130
131                                if converted:
132                                    break
133
134                        if not converted:
135                            raise TypeError(
136                                f"</> Error: Arg '{name}' must be a type of "
137                                f" {args_}, got {value}"
138                                f" ({type(value).__name__})"
139                            )
140
141                    else:
142                        if not isinstance(value, target_type):
143                            try:
144                                print(
145                                    f"</> Warning: Arg '{name}' of type {type(value)} is being"
146                                    f" converted to {target_type}"
147                                )
148                                bound.arguments[name] = target_type(value)
149                            except Exception:
150                                raise TypeError(
151                                    f"</> Error: Arg '{name}' must be a type of "
152                                    f" {target_type.__name__}, got {value}"
153                                    f" ({type(value).__name__})"
154                                )
155
156        return func(*bound.args, **bound.kwargs)

Plot the map of the quantiles for every return period for a given duration.

Parameters
  • duration: Duration of the quantile, defaults to 1
  • vmin: Minimal bounds value for the colorbar, defaults to 0
  • vmax: Maximal bounds value for the colorbar, defaults to None
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_spatial_stats( self, stats: str = 'max', vmin: float | None = 0, vmax: float | None = None, ax_settings: dict = {}, fig_settings: dict = {}, html_show: bool = False):
608    def plot_spatial_stats(
609        self,
610        stats: str = "max",
611        vmin: float | None = 0,
612        vmax: float | None = None,
613        ax_settings: dict = {},
614        fig_settings: dict = {},
615        html_show: bool = False,
616    ):
617        """
618        Plot the map of a given spatial statistic.
619        :param stats: The statistic to plot, choice are
620         'max, min, mean, median, q20, q80', defaults to "max"
621        :type stats: str, optional
622        ::param vmin: Minimal bounds value for the colorbar, defaults to 0
623        :type vmin: float, optional
624        :param vmax: Maximal bounds value for the colorbar, defaults to None
625        :type vmax: float, optional
626        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
627         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
628        :type ax_settings: dict, optional
629        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
630         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
631        :type fig_settings: dict, optional
632        :param html_show: Display the figure in an html page with your navigator, defaults
633         to False
634        :type html_show: bool, optional
635
636        """
637
638        fig_settings = plot.fig_properties(**fig_settings)
639
640        if not hasattr(self._plot_object.mystats.spatial_stats.results, stats):
641            raise ValueError(
642                f"Statistical results `{stats}` not found. Choice are: "
643                "[min, max, mean, median, q20, q80]"
644            )
645
646        stats_matrix = getattr(
647            self._plot_object.mystats.spatial_stats.results,
648            stats,
649        )
650        default_ax_settings = plot.ax_properties(
651            title="Maximal Discharges on periode"
652            f" {self._plot_object.smash.setup.start_time} -"
653            f" {self._plot_object.smash.setup.end_time}",
654            xlabel="Coords X",
655            ylabel="Coords_Y",
656            clabel="Discharge (m^3/s)",
657            cmap="viridis",
658        )
659        default_ax_settings.update(**ax_settings)
660
661        fig, ax = plot.plot_image(
662            matrice=stats_matrix,
663            bbox=geo_toolbox.get_bbox_from_smash_mesh(
664                self._parent_class.mymesh.mesh
665            ),
666            vmin=vmin,
667            vmax=vmax,
668            mask=self._plot_object.smash.mesh.active_cell,
669            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
670            ax_settings=default_ax_settings,
671            fig_settings=fig_settings,
672        )
673
674        if fig_settings.figname is None:
675            if tools.with_reticulate() or html_show:
676                mpld3.show(fig, open_browser=True)
677            else:
678                fig.show()
679
680        # return fig, ax

Plot the map of a given spatial statistic.

Parameters
  • stats: The statistic to plot, choice are 'max, min, mean, median, q20, q80', defaults to "max" ::param vmin: Minimal bounds value for the colorbar, defaults to 0
  • vmax: Maximal bounds value for the colorbar, defaults to None
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_hydrograph( self, columns: list | None = [], outlets_name: list = [], plot_rainfall: bool = True, ax_settings: dict = {}, fig_settings: dict = {}, plot_settings_sim: dict = {}, plot_settings_obs: dict = {}, html_show: bool = False):
682    def plot_hydrograph(
683        self,
684        columns: list | None = [],
685        outlets_name: list = [],
686        plot_rainfall: bool = True,
687        ax_settings: dict = {},
688        fig_settings: dict = {},
689        plot_settings_sim: dict = {},
690        plot_settings_obs: dict = {},
691        html_show: bool = False,
692    ):
693        """
694        Plot the simulated and the observed hydrogram for different outlets.
695
696        :param columns: Columns of the matrix to plot (outlets), defaults to []
697        :type columns: list | None, optional
698        :param outlets_name: List of the outlets name to plot, defaults to []
699        :type outlets_name: list, optional
700        :param plot_rainfall: Plot the rainfall on the graphics, defaults to True
701        :type plot_rainfall: bool, optional
702        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
703         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
704        :type ax_settings: dict, optional
705        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
706         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
707        :type fig_settings: dict, optional
708        :param plot_settings_sim: Parameters of the matplotlib curves. Any propoerties of
709         plot.plot_properties() class ca be defined in this dictionnary, defaults to {}
710        :type plot_settings_sim: dict, optional
711        :param plot_settings_obs: DParameters of the matplotlib curves. Any propoerties of
712         plot.plot_properties() class ca be defined in this dictionnary, defaults to {}
713        :type plot_settings_obs: dict, optional
714        :pparam html_show: Display the figure in an html page with your navigator, defaults
715         to False
716        :type html_show: bool, optional
717
718        """
719
720        fig_settings = plot.fig_properties(**fig_settings)
721
722        if len(outlets_name) > 0:
723            columns = tools.array_isin(
724                self._plot_object.smash.mesh.code,
725                np.array(outlets_name),
726            )
727        elif len(columns) > 0:
728            outlets_name = [
729                self._plot_object.smash.mesh.code[i] for i in columns
730            ]
731
732        if columns is None:
733            columns = list(
734                range(0, self._plot_object.smash.response.q.shape[0])
735            )
736            outlets_name = list(self._plot_object.smash.mesh.code)
737
738        if len(columns) == 0:
739            columns = [0]
740            outlets_name = [list(self._plot_object.smash.mesh.code)[0]]
741
742        fig, ax = plot.plot_hydrograph(
743            model=self._plot_object.smash,
744            columns=columns,
745            outlets_name=outlets_name,
746            plot_rainfall=plot_rainfall,
747            ax_settings=ax_settings,
748            fig_settings=fig_settings,
749            plot_settings_sim=plot_settings_sim,
750            plot_settings_obs=plot_settings_obs,
751        )
752
753        if fig_settings.figname is None:
754            if tools.with_reticulate() or html_show:
755                mpld3.show(fig, open_browser=True)
756            else:
757                fig.show()
758
759        # return fig, ax

Plot the simulated and the observed hydrogram for different outlets.

Parameters
  • columns: Columns of the matrix to plot (outlets), defaults to []
  • outlets_name: List of the outlets name to plot, defaults to []
  • plot_rainfall: Plot the rainfall on the graphics, defaults to True
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • plot_settings_sim: Parameters of the matplotlib curves. Any propoerties of plot.plot_properties() class ca be defined in this dictionnary, defaults to {}
  • plot_settings_obs: DParameters of the matplotlib curves. Any propoerties of plot.plot_properties() class ca be defined in this dictionnary, defaults to {} :pparam html_show: Display the figure in an html page with your navigator, defaults to False
def plot_misfit( self, columns: list | None = None, outlets_name: list = [], misfit: str = 'nse', ax_settings: dict = {}, fig_settings: dict = {}, html_show: bool = False):
761    def plot_misfit(
762        self,
763        columns: list | None = None,
764        outlets_name: list = [],
765        misfit: str = "nse",
766        ax_settings: dict = {},
767        fig_settings: dict = {},
768        html_show: bool = False,
769    ):
770        """
771        Plot a misfit criteria for a given list of outlet.
772        :param columns: Columns of the matrix to plot (outlets), defaults to []
773        :type columns: list | None, optional
774        :param outlets_name: List of the outlets name to plot, defaults to []
775        :type outlets_name: list, optional
776        :param misfit: The misfit criteria to plot, choice are
777        "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
778        :type misfit: str, optional
779        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
780         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
781        :type ax_settings: dict, optional
782        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
783         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
784        :type fig_settings: dict, optional
785        :param html_show: Display the figure in an html page with your navigator, defaults
786         to False
787        :type html_show: bool, optional
788
789        """
790
791        fig_settings = plot.fig_properties(**fig_settings)
792
793        values = getattr(
794            self._plot_object.mystats.misfit_stats.results, misfit
795        )
796
797        if len(outlets_name) > 0:
798            columns = tools.array_isin(
799                self._plot_object.smash.mesh.code,
800                np.array(outlets_name),
801            )
802
803        if columns is None:
804            columns = list(
805                range(0, self._plot_object.smash.response.q.shape[0])
806            )
807            outlets_name = self._plot_object.smash.mesh.code
808
809        fig, ax = plot.plot_misfit(
810            values=values[columns],
811            names=outlets_name,
812            columns=None,
813            misfit=misfit,
814            ax_settings=ax_settings,
815            fig_settings=fig_settings,
816        )
817
818        if fig_settings.figname is None:
819            if tools.with_reticulate() or html_show:
820                mpld3.show(fig, open_browser=True)
821            else:
822                fig.show()
823
824        # return fig, ax

Plot a misfit criteria for a given list of outlet.

Parameters
  • columns: Columns of the matrix to plot (outlets), defaults to []
  • outlets_name: List of the outlets name to plot, defaults to []
  • misfit: The misfit criteria to plot, choice are "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_outlet_stats( self, columns: list | None = None, outlets_name: list = [], stat: str = 'max', ax_settings: dict = {}, fig_settings: dict = {}, html_show: bool = False):
826    def plot_outlet_stats(
827        self,
828        columns: list | None = None,
829        outlets_name: list = [],
830        stat: str = "max",
831        ax_settings: dict = {},
832        fig_settings: dict = {},
833        html_show: bool = False,
834    ):
835        """
836        Plot a statistical criteria for a given list of outlet.
837        :param columns: Columns of the matrix to plot (outlets), defaults to []
838        :type columns: list | None, optional
839        :param outlets_name: List of the outlets name to plot, defaults to []
840        :type outlets_name: list, optional
841        :param misfit: The misfit criteria to plot, choice are
842        "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
843        :type misfit: str, optional
844        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
845         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
846        :type ax_settings: dict, optional
847        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
848         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
849        :type fig_settings: dict, optional
850        :param html_show: Display the figure in an html page with your navigator, defaults
851         to False
852        :type html_show: bool, optional
853
854        """
855
856        fig_settings = plot.fig_properties(**fig_settings)
857
858        values_sim = getattr(
859            self._plot_object.mystats.outlets_stats.results_sim, stat
860        )
861        values_obs = getattr(
862            self._plot_object.mystats.outlets_stats.results_obs, stat
863        )
864
865        if len(outlets_name) > 0:
866            columns = tools.array_isin(
867                self._plot_object.smash.mesh.code,
868                np.array(outlets_name),
869            )
870
871        if columns is None:
872            columns = list(
873                range(0, self._plot_object.smash.response.q.shape[0])
874            )
875            outlets_name = list(self._plot_object.smash.mesh.code)
876
877        fig, ax = plot.plot_outlet_stats(
878            values_sim=values_sim[columns],
879            values_obs=values_obs[columns],
880            names=outlets_name,
881            columns=None,
882            stat=stat,
883            ax_settings=ax_settings,
884            fig_settings=fig_settings,
885        )
886
887        if fig_settings.figname is None:
888            if tools.with_reticulate() or html_show:
889                mpld3.show(fig, open_browser=True)
890            else:
891                fig.show()
892
893        # return fig, ax

Plot a statistical criteria for a given list of outlet.

Parameters
  • columns: Columns of the matrix to plot (outlets), defaults to []
  • outlets_name: List of the outlets name to plot, defaults to []
  • misfit: The misfit criteria to plot, choice are "nse, nnse, rmse, nrmse, se, kge", defaults to "nse"
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def multiplot_misfit( self, columns: list | None = None, outlets_name: list = [], misfit: list = ['nse', 'nnse', 'kge', 'mse', 'rmse', 'nrmse', 'se', 'mae', 'mape', 'lgrm'], ax_settings: dict = {}, fig_settings: dict = {}, html_show: bool = False):
 895    def multiplot_misfit(
 896        self,
 897        columns: list | None = None,
 898        outlets_name: list = [],
 899        misfit: list = [
 900            "nse",
 901            "nnse",
 902            "kge",
 903            "mse",
 904            "rmse",
 905            "nrmse",
 906            "se",
 907            "mae",
 908            "mape",
 909            "lgrm",
 910        ],
 911        ax_settings: dict = {},
 912        fig_settings: dict = {},
 913        html_show: bool = False,
 914    ):
 915        """
 916        Plot misfit criterium for a given list of outlets.
 917
 918        :param columns: Columns of the matrix to plot (outlets), defaults to []
 919        :type columns: list | None, optional
 920        :param outlets_name: List of the outlets name to plot, defaults to []
 921        :type outlets_name: list, optional
 922        :param misfit: The misfit criteria to plot, list of criteria among
 923        "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
 924        :type misfit: str, optional
 925        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
 926         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
 927        :type ax_settings: dict, optional
 928        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
 929         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
 930        :type fig_settings: dict, optional
 931        :param html_show: Display the figure in an html page with your navigator, defaults
 932         to False
 933        :type html_show: bool, optional
 934
 935        """
 936
 937        fig_settings = plot.fig_properties(**fig_settings)
 938
 939        if len(outlets_name) > 0:
 940            columns = tools.array_isin(
 941                self._plot_object.smash.mesh.code,
 942                np.array(outlets_name),
 943            )
 944
 945        if columns is None:
 946            columns = list(
 947                range(0, self._plot_object.smash.response.q.shape[0])
 948            )
 949            outlets_name = list(self._plot_object.smash.mesh.code)
 950
 951        yfig = int(np.sqrt(len(misfit)))
 952        xfig = int(np.ceil(len(misfit) / yfig))
 953
 954        fig, axs = plt.subplots(
 955            xfig,
 956            yfig,
 957            constrained_layout=True,
 958        )
 959
 960        # for ax in axs:
 961        #     ax.set_axis_off()
 962
 963        for ax, crit in zip(
 964            axs.flat,
 965            misfit,
 966        ):
 967
 968            # ax.set_axis_on()
 969            ax_settings["ylabel"] = f"{crit} criteria"
 970            ax_settings["title"] = f"{crit} criteria"
 971
 972            if hasattr(self._plot_object.mystats.misfit_stats.results, crit):
 973                values = getattr(
 974                    self._plot_object.mystats.misfit_stats.results, crit
 975                )
 976            else:
 977                raise ValueError(
 978                    f"`{crit}` is not a valid statistic. choice are:"
 979                    "[nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge]"
 980                )
 981
 982            fig, ax = plot.plot_misfit(
 983                values=values[columns],
 984                names=np.array(outlets_name),
 985                columns=None,
 986                misfit=crit,
 987                figure=(fig, ax),
 988                ax_settings=ax_settings,
 989            )
 990
 991        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
 992        fig_settings.change((fig, ax))
 993
 994        if fig_settings.figname is None:
 995            if tools.with_reticulate() or html_show:
 996                mpld3.show(fig, open_browser=True)
 997            else:
 998                fig.show()
 999
1000        # return fig, ax

Plot misfit criterium for a given list of outlets.

Parameters
  • columns: Columns of the matrix to plot (outlets), defaults to []
  • outlets_name: List of the outlets name to plot, defaults to []
  • misfit: The misfit criteria to plot, list of criteria among "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_misfit_map( self, misfit: str = 'nse', coef_hydro: float = 99.0, ax_settings: dict = {}, fig_settings: dict = {}, plot_settings: dict = {}, html_show: bool = False):
1002    def plot_misfit_map(
1003        self,
1004        misfit: str = "nse",
1005        coef_hydro: float = 99.0,
1006        ax_settings: dict = {},
1007        fig_settings: dict = {},
1008        plot_settings: dict = {},
1009        html_show: bool = False,
1010    ):
1011        """
1012        Plot a map of a misfit criteria.
1013
1014        :param columns: Columns of the matrix to plot (outlets), defaults to []
1015        :type columns: list | None, optional
1016        :param outlets_name: List of the outlets name to plot, defaults to []
1017        :type outlets_name: list, optional
1018        :param misfit: The misfit criteria to plot, choice are
1019        "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
1020        :type misfit: str, optional
1021        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1022         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1023        :type ax_settings: dict, optional
1024        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1025         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1026        :type fig_settings: dict, optional
1027        :param html_show: Display the figure in an html page with your navigator, defaults
1028         to False
1029        :type html_show: bool, optional
1030
1031        """
1032
1033        if hasattr(self._plot_object.mystats.misfit_stats.results, misfit):
1034            values = getattr(
1035                self._plot_object.mystats.misfit_stats.results, misfit
1036            )
1037        else:
1038            raise ValueError(
1039                f"`{misfit}` is not a valid statistic. choice are:"
1040                "[nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge]"
1041            )
1042
1043        fig_settings = plot.fig_properties(**fig_settings)
1044
1045        name = self._plot_object.smash.mesh.code
1046        mesh = self._parent_class.mymesh.mesh
1047
1048        fig, ax = plot.plot_misfit_map(
1049            values=values,
1050            names=name,
1051            mesh=mesh,
1052            misfit=misfit,
1053            coef_hydro=coef_hydro,
1054            ax_settings=ax_settings,
1055            fig_settings=fig_settings,
1056            plot_settings=plot_settings,
1057        )
1058
1059        if fig_settings.figname is None:
1060            if tools.with_reticulate() or html_show:
1061                mpld3.show(fig, open_browser=True)
1062            else:
1063                fig.show()
1064
1065        # return fig, ax

Plot a map of a misfit criteria.

Parameters
  • columns: Columns of the matrix to plot (outlets), defaults to []
  • outlets_name: List of the outlets name to plot, defaults to []
  • misfit: The misfit criteria to plot, choice are "nse, nnse, mse, rmse, nrmse, se, mae, mape, lgrm, kge", defaults to "nse"
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def multiplot_parameters( self, mask_active_cell=False, ax_settings={}, fig_settings={}, html_show: bool = False):
1067    def multiplot_parameters(
1068        self,
1069        mask_active_cell=False,
1070        ax_settings={},
1071        fig_settings={},
1072        html_show: bool = False,
1073    ):
1074        """
1075        Multiplot map of every Smash parameters
1076        :param mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
1077        :type mask_active_cell: bool, False, optional
1078        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1079         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1080        :type ax_settings: dict, optional
1081        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1082         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1083        :type fig_settings: dict, optional
1084        :param html_show: Display the figure in an html page with your navigator, defaults
1085         to False
1086        :type html_show: bool, optional
1087
1088        """
1089
1090        default_fig_settings = plot.fig_properties(xsize=8, ysize=8)
1091        default_fig_settings.update(**fig_settings)
1092
1093        param = list(self._plot_object.smash.rr_parameters.keys)
1094
1095        if mask_active_cell:
1096            mask = self._plot_object.smash.mesh.active_cell
1097        else:
1098            mask = None
1099
1100        yfig = int(np.sqrt(len(param)))
1101        xfig = int(np.ceil(len(param) / yfig))
1102
1103        fig, axs = plt.subplots(
1104            xfig,
1105            yfig,
1106            constrained_layout=False,
1107        )
1108        plt.subplots_adjust(
1109            left=None,
1110            bottom=None,
1111            right=None,
1112            top=None,
1113            wspace=0.5,
1114            hspace=0.5,
1115        )
1116        for ax, p in zip(axs.flat, param):
1117
1118            default_ax_settings = plot.ax_properties(
1119                title=f"{p} parameters map",
1120                xlabel="Coords X",
1121                ylabel="Coords_Y",
1122                clabel=f"{p} parameter value",
1123                cmap="viridis",
1124            )
1125            default_ax_settings.update(**ax_settings)
1126
1127            z = param.index(p)
1128
1129            fig, ax = plot.plot_image(
1130                matrice=self._plot_object.smash.rr_parameters.values[:, :, z],
1131                bbox=geo_toolbox.get_bbox_from_smash_mesh(
1132                    self._parent_class.mymesh.mesh
1133                ),
1134                mask=mask,
1135                vmin=0.0,
1136                catchment_polygon=self._parent_class.mymesh.catchment_polygon,
1137                ax_settings=default_ax_settings,
1138                figure=[fig, ax],
1139            )
1140
1141        [fig.delaxes(ax) for ax in axs.flatten() if not ax.has_data()]
1142        default_fig_settings.change((fig, axs))
1143
1144        if default_fig_settings.figname is None or html_show:
1145            if tools.with_reticulate():
1146                mpld3.show(fig, open_browser=True)
1147            else:
1148                fig.show()
1149
1150        # return fig, axs

Multiplot map of every Smash parameters

Parameters
  • mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False
def plot_parameters( self, param='cp', mask_active_cell=False, vmin=0.0, vmax=None, ax_settings={}, fig_settings={}, html_show: bool = False):
1152    def plot_parameters(
1153        self,
1154        param="cp",
1155        mask_active_cell=False,
1156        vmin=0.0,
1157        vmax=None,
1158        ax_settings={},
1159        fig_settings={},
1160        html_show: bool = False,
1161    ):
1162        """
1163        Plot a map of a Smash parameters
1164        :param param: Name of the parameter to plot, defaults to "cp"
1165        :type param: str, optional
1166        :param mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
1167        :type mask_active_cell: bool, False, optional
1168        :param vmin: Minimum value of the colorbar, defaults to 0.0
1169        :type vmin: float, optional
1170        :param vmax: Maximum value of the colorbar, defaults to None
1171        :type vmax: float, optional
1172        :param ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of
1173         plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
1174        :type ax_settings: dict, optional
1175        :param fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of
1176         plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
1177        :type fig_settings: dict, optional
1178        :param html_show: Display the figure in an html page with your navigator, defaults
1179         to False
1180        :type html_show: bool, optional
1181        """
1182
1183        fig_settings = plot.fig_properties(**fig_settings)
1184
1185        list_param = list(self._plot_object.smash.rr_parameters.keys)
1186        z = list_param.index(param)
1187
1188        if mask_active_cell:
1189            mask = self._plot_object.smash.mesh.active_cell
1190        else:
1191            mask = None
1192
1193        fig, axs = plt.subplots()
1194
1195        default_ax_settings = plot.ax_properties(
1196            title=f"{param} parameters map",
1197            xlabel="Coords X",
1198            ylabel="Coords_Y",
1199            clabel=f"{param} parameter value",
1200            cmap="viridis",
1201        )
1202        default_ax_settings.update(**ax_settings)
1203
1204        fig, ax = plot.plot_image(
1205            matrice=self._plot_object.smash.rr_parameters.values[:, :, z],
1206            bbox=geo_toolbox.get_bbox_from_smash_mesh(
1207                self._parent_class.mymesh.mesh
1208            ),
1209            mask=mask,
1210            vmin=vmin,
1211            vmax=vmax,
1212            catchment_polygon=self._parent_class.mymesh.catchment_polygon,
1213            ax_settings=default_ax_settings,
1214        )
1215
1216        fig_settings.change((fig, axs))
1217
1218        if fig_settings.figname is None or html_show:
1219            if tools.with_reticulate():
1220                mpld3.show(fig, open_browser=True)
1221            else:
1222                fig.show()
1223
1224        # return fig, axs

Plot a map of a Smash parameters

Parameters
  • param: Name of the parameter to plot, defaults to "cp"
  • mask_active_cell: Use the mask of the active cell to hide the non-active cell, defaults to False
  • vmin: Minimum value of the colorbar, defaults to 0.0
  • vmax: Maximum value of the colorbar, defaults to None
  • ax_settings: Parameters of the matplotlib figure 'ax'. Any propoerties of plot.ax_properties() class ca be defined in this dictionnary, defaults to {}
  • fig_settings: Parameters of the matplotlib figure 'fig'. Any propoerties of plot.fig_properties() class ca be defined in this dictionnary, defaults to {}
  • html_show: Display the figure in an html page with your navigator, defaults to False