diff --git a/src/View/Results/PlotSedAdisDx.py b/src/View/Results/PlotSedAdis.py similarity index 64% rename from src/View/Results/PlotSedAdisDx.py rename to src/View/Results/PlotSedAdis.py index 489f1678..6431b6ca 100644 --- a/src/View/Results/PlotSedAdisDx.py +++ b/src/View/Results/PlotSedAdis.py @@ -35,11 +35,11 @@ _translate = QCoreApplication.translate logger = logging.getLogger() -class PlotAdis_dx(PamhyrPlot): +class PlotAdis(PamhyrPlot): def __init__(self, canvas=None, trad=None, toolbar=None, results=None, reach_id=0, profile_id=0, pol_id=[0], key="C", type_pol=[7], parent=None): - super(PlotAdis_dx, self).__init__( + super(PlotAdis, self).__init__( canvas=canvas, trad=trad, data=results, @@ -106,114 +106,15 @@ class PlotAdis_dx(PamhyrPlot): self._init = False return - self.draw_min_and_max(reach) - self.draw_data(reach) - self.draw_profiles_hs(reach) - self.draw_current(reach) - - self.enable_legend() + self.draw_min_and_max() + self.draw_data() + self.draw_current() self.idle() - #self.update_current() self._init = True - def draw_profiles_hs(self, reach): - lhs = filter( - lambda hs: hs._input_reach.reach is reach.geometry, - filter( - lambda hs: hs._input_reach is not None, - self.results.study.river.hydraulic_structures.lst - ) - ) - - for hs in lhs: - x = hs.input_rk - z_min = reach.geometry.get_z_min() - z_max = reach.geometry.get_z_max() - - self.canvas.axes.plot( - [x, x], - [min(z_min), max(z_max)], - linestyle="--", - lw=1., - color=self.color_plot_previous, - ) - - self.canvas.axes.annotate( - " > " + hs.name, - (x, max(z_max)), - horizontalalignment='left', - verticalalignment='top', - annotation_clip=True, - fontsize=9, color=self.color_plot_previous, - ) - - def draw_data(self, reach): - profile = reach.profile(self._current_profile_id) - x = reach.geometry.get_rk() - - for i in range(len(self._current_pol_id)): - pol_id = self._current_pol_id[i] - if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: - y = [0.0]*len(x) - else: - y = list(map(lambda p: - p.get_ts_key( - self._current_timestamp, "pols" - )[pol_id][self.val_id[self._key]], - reach.profiles)) - self._lines.append(self.canvas.axes.plot( - x, y, - label=self.label[self._key], - color=self.color_plot, - **self.plot_default_kargs - )[0]) - #self.set_y_lim() - - def draw_current(self, reach): - - rk = reach.geometry.get_rk() - self._current, = self.canvas.axes.plot( - [rk[self._current_profile_id], rk[self._current_profile_id]], - self.canvas.axes.get_ylim(), - #[self.y_max, self.y_min], - color="grey", - linestyle="dashed", - lw=1., - ) - - def update_current(self): - self.hide_current() - self.canvas.axes.relim(visible_only=True) - self.canvas.axes.autoscale_view() - self.show_current() - reach = self.results.river.reach(self._current_reach_id) - rk = reach.geometry.get_rk() - self._current.set_data( - [rk[self._current_profile_id], rk[self._current_profile_id]], - self.canvas.axes.get_ylim() - ) - - def draw_min_and_max(self, reach): - profile = reach.profile(self._current_profile_id) - x = reach.geometry.get_rk() - - y = [-inf]*reach.geometry.number_profiles - z = [inf]*reach.geometry.number_profiles - for pol_id in self._current_pol_id: - if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: - for i in range(reach.geometry.number_profiles): - y[i] = max(0.0, y[i]) - z[i] = min(0.0, z[i]) - else: - val_id = self.val_id[self._key] - for i, p in enumerate(reach.profiles): - rk_y = list(map(lambda data_el: - data_el[pol_id][val_id], - p.get_key("pols") - )) - y[i] = max(np.max(rk_y), y[i]) - z[i] = min(np.min(rk_y), z[i]) + def draw_min_and_max(self): + x, y, z = self.get_min_and_max() self._line_max, = self.canvas.axes.plot( x, y, @@ -233,53 +134,82 @@ class PlotAdis_dx(PamhyrPlot): markersize=0 ) + def update_min_and_max(self): + x, y, z = self.get_min_and_max() + + self._line_max.set_data(x, y) + self._line_min.set_data(x, z) + def set_reach(self, reach_id): self._current_reach_id = reach_id self._current_profile_id = 0 self.draw() - def set_profile(self, profile_id): - self._current_profile_id = profile_id - self.update_current() - self.update_idle() - - def set_timestamp(self, timestamp): - self._current_timestamp = timestamp - self.update() - def update(self): if not self._init: self.draw() self.update_min_and_max() self.update_data() - #self.set_y_lim self.update_idle() - def update_min_and_max(self): + def hide_current(self): + self._current.set_visible(False) + + def show_current(self): + self._current.set_visible(True) + + def set_pollutant(self, pol_id): + for l in self._lines: + l.remove() + self._lines = [] + self._current_pol_id = pol_id + self.update_min_and_max() + self.draw_data() + self.update_current() + self.update_idle() + +class PlotAdis_dx(PlotAdis): + def __init__(self, canvas=None, trad=None, toolbar=None, + results=None, reach_id=0, profile_id=0, + pol_id=[0], key="C", type_pol=[7], parent=None): + super(PlotAdis_dx, self).__init__( + canvas=canvas, + trad=trad, + toolbar=toolbar, + results=results, + reach_id=reach_id, + profile_id=profile_id, + pol_id=pol_id, + key=key, + type_pol=type_pol, + parent=parent + ) + + def draw_data(self): reach = self.results.river.reach(self._current_reach_id) profile = reach.profile(self._current_profile_id) x = reach.geometry.get_rk() - y = [-inf]*reach.geometry.number_profiles - z = [inf]*reach.geometry.number_profiles - for pol_id in self._current_pol_id: + for i in range(len(self._current_pol_id)): + pol_id = self._current_pol_id[i] + name = self.data.pollutants_list[pol_id] if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: - for i in range(reach.geometry.number_profiles): - y[i] = max(0.0, y[i]) - z[i] = min(0.0, z[i]) + y = [0.0]*len(x) else: - val_id = self.val_id[self._key] - for i, p in enumerate(reach.profiles): - rk_y = list(map(lambda data_el: - data_el[pol_id][val_id], - p.get_key("pols") - )) - y[i] = max(np.max(rk_y), y[i]) - z[i] = min(np.min(rk_y), z[i]) + y = list(map(lambda p: + p.get_ts_key( + self._current_timestamp, "pols" + )[pol_id][self.val_id[self._key]], + reach.profiles)) + self._lines.append(self.canvas.axes.plot( + x, y, + label=self.label[self._key]+" "+name, + color=self.color_plot, + **self.plot_default_kargs + )[0]) - self._line_max.set_data(x, y) - self._line_min.set_data(x, z) + self.enable_legend() def update_data(self): reach = self.results.river.reach(self._current_reach_id) @@ -302,44 +232,186 @@ class PlotAdis_dx(PamhyrPlot): self.update_current() - def hide_current(self): - self._current.set_visible(False) - - def show_current(self): - self._current.set_visible(True) - - def set_pollutant(self, pol_id): - for l in self._lines: - l.remove() - self._lines = [] - reach = self.results.river.reach(self._current_reach_id) - self._current_pol_id = pol_id - self.update_min_and_max() - self.draw_data(reach) - self.update_current() - #self.set_y_lim - self.update_idle() - - def set_y_lim(self): + def draw_current(self): reach = self.results.river.reach(self._current_reach_id) + rk = reach.geometry.get_rk() - y0 = [] + self._current, = self.canvas.axes.plot( + [rk[self._current_profile_id], rk[self._current_profile_id]], + self.canvas.axes.get_ylim(), + color="grey", + linestyle="dashed", + lw=1., + ) + + def update_current(self): + self.hide_current() + self.canvas.axes.relim(visible_only=True) + self.canvas.axes.autoscale_view() + self.show_current() + reach = self.results.river.reach(self._current_reach_id) + rk = reach.geometry.get_rk() + self._current.set_data( + [rk[self._current_profile_id], rk[self._current_profile_id]], + self.canvas.axes.get_ylim() + ) + + def get_min_and_max(self): + reach = self.results.river.reach(self._current_reach_id) + profile = reach.profile(self._current_profile_id) + x = reach.geometry.get_rk() + + y = [-inf]*reach.geometry.number_profiles + z = [inf]*reach.geometry.number_profiles for pol_id in self._current_pol_id: if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: - y = [0.0] + for i in range(reach.geometry.number_profiles): + y[i] = max(0.0, y[i]) + z[i] = min(0.0, z[i]) else: val_id = self.val_id[self._key] - y = list( - map(lambda p: - list(map(lambda data_el: - data_el[pol_id][val_id], - p.get_key("pols"))), reach.profiles)) - y0.append(y) + for i, p in enumerate(reach.profiles): + rk_y = list(map(lambda data_el: + data_el[pol_id][val_id], + p.get_key("pols") + )) + y[i] = max(np.max(rk_y), y[i]) + z[i] = min(np.min(rk_y), z[i]) - self.y_max = np.max([np.max(y) for y in y0]) - self.y_min = np.min([np.min(y) for y in y0]) - if self.y_max - self.y_min < 0.000001: - self.y_min = (self.y_max + self.y_min)/2 - 0.5 - self.y_max = (self.y_max + self.y_min)/2 + 0.5 + return x, y, z - self.canvas.axes.set_ylim(self.y_min, self.y_max) + def set_profile(self, profile_id): + self._current_profile_id = profile_id + self.update_current() + self.update_idle() + + def set_timestamp(self, timestamp): + self._current_timestamp = timestamp + self.update() + + +class PlotAdis_dt(PlotAdis): + def __init__(self, canvas=None, trad=None, toolbar=None, + results=None, reach_id=0, profile_id=0, + pol_id=[0], key="C", type_pol=[7], parent=None): + super(PlotAdis_dt, self).__init__( + canvas=canvas, + trad=trad, + toolbar=toolbar, + results=results, + reach_id=reach_id, + profile_id=profile_id, + pol_id=pol_id, + key=key, + type_pol=type_pol, + parent=parent + ) + + def draw_data(self): + reach = self.results.river.reach(self._current_reach_id) + profile = reach.profile(self._current_profile_id) + self.ts = list(self.results.get("timestamps")) + self.ts.sort() + + x = self.ts + for i in range(len(self._current_pol_id)): + pol_id = self._current_pol_id[i] + name = self.data.pollutants_list[pol_id] + if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: + y = [0.0]*len(x) + else: + val_id = self.val_id[self._key] + y = list(map(lambda data_el: + data_el[pol_id][val_id], + profile.get_key("pols") + )) + + self._lines.append(self.canvas.axes.plot( + x, y, + label=self.label[self._key]+" "+name, + color=self.color_plot, + **self.plot_default_kargs + )[0]) + + self.set_ticks_time_formater() + self.enable_legend() + + def update_data(self): + reach = self.results.river.reach(self._current_reach_id) + profile = reach.profile(self._current_profile_id) + + x = self.ts + for i in range(len(self._current_pol_id)): + pol_id = self._current_pol_id[i] + if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: + y = [0.0]*len(x) + else: + y = list(map(lambda data_el: + data_el[pol_id][self.val_id[self._key]], + profile.get_key("pols") + )) + + self._lines[i].set_data(x, y) + + self._current.set_data( + [self._current_timestamp, self._current_timestamp], + self.canvas.axes.get_ylim() + ) + + self.update_current() + + def draw_current(self): + self._current, = self.canvas.axes.plot( + [self._current_timestamp, self._current_timestamp], + self.canvas.axes.get_ylim(), + color="grey", + linestyle="dashed", + lw=1., + ) + + def update_current(self): + self.hide_current() + self.canvas.axes.relim(visible_only=True) + self.canvas.axes.autoscale_view() + self.show_current() + self._current.set_data( + [self._current_timestamp, self._current_timestamp], + self.canvas.axes.get_ylim() + ) + + def get_min_and_max(self): + reach = self.results.river.reach(self._current_reach_id) + self.ts = list(self.results.get("timestamps")) + self.ts.sort() + + x = self.ts + + y = [-inf]*len(x) + z = [inf]*len(x) + for pol_id in self._current_pol_id: + if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: + for i in range(len(x)): + y[i] = max(0.0, y[i]) + z[i] = min(0.0, z[i]) + else: + val_id = self.val_id[self._key] + for i, ts in enumerate(x): + ts_y = list(map(lambda p: + p.get_ts_key( + ts, "pols" + )[pol_id][val_id], + reach.profiles + )) + y[i] = max(np.max(ts_y), y[i]) + z[i] = min(np.min(ts_y), z[i]) + + return x, y, z + + def set_profile(self, profile_id): + self._current_profile_id = profile_id + self.update() + + def set_timestamp(self, timestamp): + self._current_timestamp = timestamp + self.update_current() + self.update_idle() diff --git a/src/View/Results/PlotSedAdisDt.py b/src/View/Results/PlotSedAdisDt.py deleted file mode 100644 index a9888e67..00000000 --- a/src/View/Results/PlotSedAdisDt.py +++ /dev/null @@ -1,270 +0,0 @@ -# PlotSedAdisDt.py -- Pamhyr -# Copyright (C) 2023-2024 INRAE -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# -*- coding: utf-8 -*- - -import logging -import numpy as np - -from functools import reduce -from datetime import datetime - -from tools import timer, trace -from View.Tools.PamhyrPlot import PamhyrPlot - -from PyQt5.QtCore import ( - QCoreApplication -) - -_translate = QCoreApplication.translate - -logger = logging.getLogger() - - -class PlotAdis_dt(PamhyrPlot): - def __init__(self, canvas=None, trad=None, toolbar=None, - results=None, reach_id=0, profile_id=0, - pol_id=[0], key="C", type_pol=[7], parent=None): - super(PlotAdis_dt, self).__init__( - canvas=canvas, - trad=trad, - data=results, - toolbar=toolbar, - parent=parent - ) - - self._current_timestamp = max(results.get("timestamps")) - self._current_reach_id = reach_id - self._current_profile_id = profile_id - self._current_pol_id = pol_id - self._key = key - self._type_pol = type_pol - - self.label_x = self._trad["unit_time_s"] - self._available_values_y = self._trad.get_dict("values_y_pol") - - self.label = {} - self.label_max = {} - self.label_min = {} - self.label["C"] = _translate("Results", "Concentration") - self.label_max["C"] = _translate("Results", "Max Concentration") - if self._type_pol[pol_id[0]] == -1: # Total - self.label["M"] = _translate("Results", "Thickness") - self.label_max["M"] = _translate("Results", "Max Thickness") - self.label_min["M"] = _translate("Results", "Min Thickness") - self.label_y = self._available_values_y["unit_thickness"] - else: - self.label["M"] = _translate("Results", "Mass") - self.label_max["M"] = _translate("Results", "Max Mass") - self.label_min["M"] = _translate("Results", "Min Mass") - self.label_y = self._available_values_y["unit_"+self._key] - self.val_id = {} - self.val_id["C"] = 0 - self.val_id["G"] = 1 - self.val_id["M"] = 2 - self.val_id["D"] = 3 - - self._lines = [None]*len(self._current_pol_id) - - self._isometric_axis = False - - @property - def results(self): - return self.data - - @results.setter - def results(self, results): - self.data = results - self._current_timestamp = max(results.get("timestamps")) - - @timer - def draw(self, highlight=None): - self.init_axes() - - if self.results is None: - return - - reach = self.results.river.reach(self._current_reach_id) - profile = reach.profile(self._current_profile_id) - - if reach.geometry.number_profiles == 0: - self._init = False - return - - self.draw_max(reach) - self.draw_data(reach, profile) - self.draw_current() - - self.set_ticks_time_formater() - - self.enable_legend() - - self.idle() - self.update_current() - self._init = True - - def draw_data(self, reach, profile): - self.ts = list(self.results.get("timestamps")) - self.ts.sort() - - x = self.ts - for i in range(len(self._current_pol_id)): - pol_id = self._current_pol_id[i] - if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: - y = [0.0]*len(x) - else: - val_id = self.val_id[self._key] - y = list(map(lambda data_el: - data_el[pol_id][val_id], - profile.get_key("pols") - )) - - self._lines[i], = self.canvas.axes.plot( - x, y, - label=self.label[self._key], - color=self.color_plot, - **self.plot_default_kargs - ) - - def draw_current(self): - self._current, = self.canvas.axes.plot( - [self._current_timestamp, self._current_timestamp], - self.canvas.axes.get_ylim(), - color="grey", - linestyle="dashed", - lw=1., - ) - - def draw_max(self, reach): - self.ts = list(self.results.get("timestamps")) - self.ts.sort() - - x = self.ts - if self.val_id[self._key] > 0 and self._type_pol == 1: - y = [0.0]*len(x) - else: - y = [] - val_id = self.val_id[self._key] - for ts in x: - ts_y = list(map(lambda p: - p.get_ts_key( - ts, "pols" - )[self._current_pol_id[0]][val_id], - reach.profiles)) - y.append(np.max(ts_y)) - - self._line_max, = self.canvas.axes.plot( - x, y, - label=self.label_max[self._key], - color=self.color_plot_highlight, - linestyle='dotted', - lw=1., - markersize=0 - ) - - def set_reach(self, reach_id): - self._current_reach_id = reach_id - self._current_profile_id = 0 - self.draw() - - def set_profile(self, profile_id): - self._current_profile_id = profile_id - self.update() - - def set_timestamp(self, timestamp): - self._current_timestamp = timestamp - self.update_current() - self.update_idle() - - def update(self): - if not self._init: - self.draw() - - self.update_max() - self.update_data() - self.update_idle() - - def update_max(self): - reach = self.results.river.reach(self._current_reach_id) - self.ts = list(self.results.get("timestamps")) - self.ts.sort() - - x = self.ts - if self.val_id[self._key] > 0 and self._type_pol == 1: - y = [0.0]*len(x) - else: - y = [] - val_id = self.val_id[self._key] - for ts in x: - ts_y = list(map(lambda p: - p.get_ts_key( - ts, "pols" - )[self._current_pol_id[0]][val_id], - reach.profiles)) - y.append(np.max(ts_y)) - - self._line_max.set_data(x, y) - - def update_data(self): - reach = self.results.river.reach(self._current_reach_id) - profile = reach.profile(self._current_profile_id) - - x = self.ts - for i in range(len(self._current_pol_id)): - pol_id = self._current_pol_id[i] - if self.val_id[self._key] > 0 and self._type_pol[pol_id] == 1: - y = [0.0]*len(x) - else: - y = list(map(lambda data_el: - data_el[pol_id][self.val_id[self._key]], - profile.get_key("pols") - )) - - self._lines[i].set_data(x, y) - - self._current.set_data( - [self._current_timestamp, self._current_timestamp], - self.canvas.axes.get_ylim() - ) - - self.hide_current() - self.canvas.axes.relim(visible_only=True) - self.canvas.axes.autoscale_view() - self.show_current() - - def update_current(self): - self._current.set_data( - [self._current_timestamp, self._current_timestamp], - self.canvas.axes.get_ylim() - ) - - def hide_current(self): - self._current.set_visible(False) - - def show_current(self): - self._current.set_visible(True) - - def set_pollutant(self, pol_id): - if len(pol_id) == len(self._current_pol_id): - self._current_pol_id = pol_id - self.update() - self.update_current() - else: - self._current_pol_id = pol_id - self._lines = [None]*len(self._current_pol_id) - self.draw() - self.update_current() - diff --git a/src/View/Results/WindowAdisTS.py b/src/View/Results/WindowAdisTS.py index ff89d36a..9a11d3c5 100644 --- a/src/View/Results/WindowAdisTS.py +++ b/src/View/Results/WindowAdisTS.py @@ -46,8 +46,8 @@ from PyQt5.QtWidgets import ( from View.Tools.Plot.PamhyrCanvas import MplCanvas from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar -from View.Results.PlotSedAdisDt import PlotAdis_dt -from View.Results.PlotSedAdisDx import PlotAdis_dx +#from View.Results.PlotSedAdisDt import PlotAdis_dt +from View.Results.PlotSedAdisDx import PlotAdis_dx, PlotAdis_dt from View.Results.CustomPlot.Plot import CustomPlot from View.Results.CustomPlot.CustomPlotValuesSelectionDialog import ( @@ -276,9 +276,6 @@ class ResultsWindowAdisTS(PamhyrWindow): self.plot_mdt.draw() - #if self._type_pol[self._pol_id[0]] != 7: - #self.find(QTabWidget, "tabWidget").setTabVisible(2, False) - # Thickness self.canvas_tdx = MplCanvas(width=5, height=4, dpi=100) @@ -481,7 +478,6 @@ class ResultsWindowAdisTS(PamhyrWindow): if reach_id is not None: self.plot_cdt.set_reach(reach_id) self.plot_cdx.set_reach(reach_id) - #if self._type_pol[self._pol_id[0]] != 1: self.plot_mdx.set_reach(reach_id) self.plot_mdt.set_reach(reach_id) self.plot_tdt.set_reach(reach_id) @@ -493,7 +489,6 @@ class ResultsWindowAdisTS(PamhyrWindow): if profile_id is not None: self.plot_cdt.set_profile(profile_id) self.plot_cdx.set_profile(profile_id) - #if self._type_pol[self._pol_id[0]] != 1: self.plot_mdx.set_profile(profile_id) self.plot_mdt.set_profile(profile_id) self.plot_tdt.set_profile(profile_id) @@ -505,14 +500,9 @@ class ResultsWindowAdisTS(PamhyrWindow): self._pol_id = [p+1 for p in pol_id] # remove total_sediment self.plot_cdt.set_pollutant(self._pol_id) self.plot_cdx.set_pollutant(self._pol_id) - #if self._type_pol[self._pol_id[0]] != 1: - #self.find(QTabWidget, "tabWidget").setTabVisible(2, True) - #self.plot_mdx.set_pollutant(self._pol_id) - #self.plot_mdt.set_pollutant(self._pol_id) - #else: - #self.find(QTabWidget, "tabWidget").setTabVisible(2, False) + self.plot_mdx.set_pollutant(self._pol_id) + self.plot_mdt.set_pollutant(self._pol_id) - #self.update_table_selection_pol(self._pol_id) if timestamp is not None: self.plot_cdt.set_timestamp(timestamp) @@ -573,17 +563,15 @@ class ResultsWindowAdisTS(PamhyrWindow): def _reload_plots(self): self.plot_cdt.results = self._results self.plot_cdx.results = self._results - if self._type_pol[self._pol_id] == 7: - self.plot_mdx.results = self._results - self.plot_mdt.results = self._results + self.plot_mdx.results = self._results + self.plot_mdt.results = self._results self.plot_tdt.results = self._results self.plot_tdx.results = self._results self.plot_cdt.draw() self.plot_cdx.draw() - if self._type_pol[self._pol_id] == 7: - self.plot_mdx.draw() - self.plot_mdt.draw() + self.plot_mdx.draw() + self.plot_mdt.draw() self.plot_tdt.draw() self.plot_tdx.draw()