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