From b77aed23952d5bc0f8634d6d5a3f086c5ca1da67 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Mon, 16 Oct 2023 15:52:29 +0200 Subject: [PATCH 01/10] results: Add custom plot dialog scheme. --- .../CustomPlotValuesSelectionDialog.py | 87 +++++++++++++++++ src/View/Results/Window.py | 21 +++++ .../ui/CustomPlotValuesSelectionDialog.ui | 93 +++++++++++++++++++ src/View/ui/Results.ui | 24 +++++ 4 files changed, 225 insertions(+) create mode 100644 src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py create mode 100644 src/View/ui/CustomPlotValuesSelectionDialog.ui diff --git a/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py new file mode 100644 index 00000000..d2e3a3e8 --- /dev/null +++ b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py @@ -0,0 +1,87 @@ +# CustomPlotValueSelectionDialog.py -- Pamhyr +# Copyright (C) 2023 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 -*- + +from View.Tools.PamhyrWindow import PamhyrDialog + +from PyQt5.QtWidgets import ( + QRadioButton, QCheckBox, QVBoxLayout, +) + +class CustomPlotValuesSelectionDialog(PamhyrDialog): + _pamhyr_ui = "CustomPlotValuesSelectionDialog" + _pamhyr_name = "Custom Plot Selection" + + def __init__(self, parent=None): + super(CustomPlotValuesSelectionDialog, self).__init__( + title=self._pamhyr_name, + options=[], + parent=parent + ) + + self._available_values_x = ['foo', 'bar'] + self._available_values_y = ['bar', 'baz'] + + self.setup_radio_buttons() + self.setup_check_boxs() + + self.value = None + + def setup_radio_buttons(self): + self._radio = [] + layout = self.find(QVBoxLayout, "verticalLayout_x") + + for value in self._available_values_x: + btn = QRadioButton(value, parent=self) + self._radio.append(btn) + layout.addWidget(btn) + + self._radio[0].setChecked(True) + layout.addStretch() + + def setup_check_boxs(self): + self._check = [] + layout = self.find(QVBoxLayout, "verticalLayout_y") + + for value in self._available_values_y: + btn = QCheckBox(value, parent=self) + self._check.append(btn) + layout.addWidget(btn) + + self._check[0].setChecked(True) + layout.addStretch() + + def accept(self): + x = next( + filter( + lambda r: r.isChecked(), + self._radio + ) + ).text() + + y = list( + map( + lambda b: b.text(), + filter( + lambda b: b.isChecked(), + self._check + ) + ) + ) + + self.value = x, y + super().accept() diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index 15167fd3..353a036c 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -51,6 +51,10 @@ from View.Results.PlotH import PlotH from View.Results.PlotSedReach import PlotSedReach from View.Results.PlotSedProfile import PlotSedProfile +from View.Results.CustomPlot.CustomPlotValuesSelectionDialog import ( + CustomPlotValuesSelectionDialog, +) + from View.Results.Table import TableModel from View.Results.translate import ResultsTranslate from View.Stricklers.Window import StricklersWindow @@ -272,6 +276,17 @@ class ResultsWindow(PamhyrWindow): self._status_label.setText(txt) def setup_connections(self): + # Action + actions = { + "action_add": self._add_custom_plot + } + + for action in actions: + self.find(QAction, action).triggered.connect( + actions[action] + ) + + # Table and Plot fun = { "reach": self._set_current_reach, "profile": self._set_current_profile, @@ -390,6 +405,12 @@ class ResultsWindow(PamhyrWindow): timestamp = self._timestamps[self._slider_time.value()] self.update(timestamp=timestamp) + def _add_custom_plot(self): + dlg = CustomPlotValuesSelectionDialog(parent=self) + if dlg.exec(): + value = dlg.value + logger.info(value) + def _copy(self): logger.info("TODO: copy") diff --git a/src/View/ui/CustomPlotValuesSelectionDialog.ui b/src/View/ui/CustomPlotValuesSelectionDialog.ui new file mode 100644 index 00000000..88ca363c --- /dev/null +++ b/src/View/ui/CustomPlotValuesSelectionDialog.ui @@ -0,0 +1,93 @@ + + + Dialog + + + + 0 + 0 + 414 + 482 + + + + Dialog + + + + + + Qt::Horizontal + + + + + + + X axis: + + + + + + + + + + + Y axis: + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/View/ui/Results.ui b/src/View/ui/Results.ui index 5b797724..08920821 100644 --- a/src/View/ui/Results.ui +++ b/src/View/ui/Results.ui @@ -140,6 +140,30 @@ + + + toolBar + + + TopToolBarArea + + + false + + + + + + + ressources/gtk-add.pngressources/gtk-add.png + + + Add + + + Add custom visualization + + From 98ee3ee6eca0b845320238d29766cb11e926dc9c Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Mon, 16 Oct 2023 17:25:08 +0200 Subject: [PATCH 02/10] CustomPlot: Add translation. --- .../CustomPlotValuesSelectionDialog.py | 36 +++++++---- src/View/Results/CustomPlot/Translate.py | 61 +++++++++++++++++++ 2 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 src/View/Results/CustomPlot/Translate.py diff --git a/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py index d2e3a3e8..1ffd6732 100644 --- a/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py +++ b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py @@ -1,4 +1,4 @@ -# CustomPlotValueSelectionDialog.py -- Pamhyr +# CustomPlotValuesSelectionDialog.py -- Pamhyr # Copyright (C) 2023 INRAE # # This program is free software: you can redistribute it and/or modify @@ -22,6 +22,9 @@ from PyQt5.QtWidgets import ( QRadioButton, QCheckBox, QVBoxLayout, ) +from View.Results.CustomPlot.Translate import CustomPlotTranslate + + class CustomPlotValuesSelectionDialog(PamhyrDialog): _pamhyr_ui = "CustomPlotValuesSelectionDialog" _pamhyr_name = "Custom Plot Selection" @@ -30,11 +33,12 @@ class CustomPlotValuesSelectionDialog(PamhyrDialog): super(CustomPlotValuesSelectionDialog, self).__init__( title=self._pamhyr_name, options=[], + trad=CustomPlotTranslate(), parent=parent ) - self._available_values_x = ['foo', 'bar'] - self._available_values_y = ['bar', 'baz'] + self._available_values_x = self._trad.get_dict("values_x") + self._available_values_y = self._trad.get_dict("values_y") self.setup_radio_buttons() self.setup_check_boxs() @@ -46,11 +50,14 @@ class CustomPlotValuesSelectionDialog(PamhyrDialog): layout = self.find(QVBoxLayout, "verticalLayout_x") for value in self._available_values_x: - btn = QRadioButton(value, parent=self) - self._radio.append(btn) + btn = QRadioButton( + self._available_values_x[value], + parent=self + ) + self._radio.append((value, btn)) layout.addWidget(btn) - self._radio[0].setChecked(True) + self._radio[0][1].setChecked(True) layout.addStretch() def setup_check_boxs(self): @@ -58,26 +65,29 @@ class CustomPlotValuesSelectionDialog(PamhyrDialog): layout = self.find(QVBoxLayout, "verticalLayout_y") for value in self._available_values_y: - btn = QCheckBox(value, parent=self) - self._check.append(btn) + btn = QCheckBox( + self._available_values_y[value], + parent=self + ) + self._check.append((value, btn)) layout.addWidget(btn) - self._check[0].setChecked(True) + self._check[0][1].setChecked(True) layout.addStretch() def accept(self): x = next( filter( - lambda r: r.isChecked(), + lambda r: r[1].isChecked(), self._radio ) - ).text() + )[0] y = list( map( - lambda b: b.text(), + lambda b: b[0], filter( - lambda b: b.isChecked(), + lambda b: b[1].isChecked(), self._check ) ) diff --git a/src/View/Results/CustomPlot/Translate.py b/src/View/Results/CustomPlot/Translate.py new file mode 100644 index 00000000..11c3187e --- /dev/null +++ b/src/View/Results/CustomPlot/Translate.py @@ -0,0 +1,61 @@ +# Translate.py -- Pamhyr +# Copyright (C) 2023 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 -*- + +from PyQt5.QtCore import QCoreApplication + +from View.Results.translate import ResultsTranslate + +_translate = QCoreApplication.translate + + +class CustomPlotTranslate(ResultsTranslate): + def __init__(self): + super(CustomPlotTranslate, self).__init__() + + self._dict['time'] = _translate( + "CustomPlot", "Time (sec)" + ) + + self._dict['kp'] = _translate( + "CustomPlot", "Kp (m)" + ) + + self._dict['elevation'] = _translate( + "CustomPlot", "Elevation (m)" + ) + + self._dict['water_elevation'] = _translate( + "CustomPlot", "Water elevation (m)" + ) + + self._dict['discharge'] = _translate( + "CustomPlot", "Discharge (m³/s)" + ) + + # SubDict + + self._sub_dict["values_x"] = { + "kp": self._dict["kp"], + "time": self._dict["time"], + } + + self._sub_dict["values_y"] = { + "elevation": self._dict["elevation"], + "water_elevation": self._dict["water_elevation"], + "discharge": self._dict["discharge"], + } From daaa9b193ee7397a927a699d5b63a25dc22e746e Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Tue, 17 Oct 2023 11:18:35 +0200 Subject: [PATCH 03/10] Resutls: CustomPlot: Prepare ploting mecanisme. --- src/View/Results/CustomPlot/Plot.py | 112 +++++++++++++++++++++++ src/View/Results/CustomPlot/Translate.py | 16 +++- src/View/Results/Window.py | 75 ++++++++++++++- 3 files changed, 195 insertions(+), 8 deletions(-) create mode 100644 src/View/Results/CustomPlot/Plot.py diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py new file mode 100644 index 00000000..ea1e2001 --- /dev/null +++ b/src/View/Results/CustomPlot/Plot.py @@ -0,0 +1,112 @@ +# Plot.py -- Pamhyr +# Copyright (C) 2023 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 + +from functools import reduce + +from tools import timer +from View.Tools.PamhyrPlot import PamhyrPlot + +logger = logging.getLogger() + +unit = { + "elevation": "meter", + "water_elevation": "meter", + "discharge": "m3s", +} + + +class CustomPlot(PamhyrPlot): + def __init__(self, x, y, reach, profile, timestamp, + data=None, canvas=None, trad=None, + toolbar=None, parent=None): + super(CustomPlot, self).__init__( + canvas=canvas, + trad=trad, + data=data, + toolbar=toolbar, + parent=parent + ) + + self._x = x + self._y = y + self._reach = reach + self._profile = profile + self._timestamp = timestamp + + self._y_axis = list( + set( + map( + lambda y: self._trad[y], + self._y + ) + ) + ) + + @timer + def draw(self): + self.canvas.axes.cla() + self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5) + + if self.data is None: + return + + self.canvas.axes.set_xlabel( + self._trad[self._x], + color='green', fontsize=12 + ) + self.canvas.axes.set_ylabel( + self._trad[self._y_axis[0]], + color='green', fontsize=12 + ) + + for axes in self._y_axis[1:]: + logger.info(axes) + ax_new = ax.twinx() + #ax_new.spines['right'].set_position(('axes', 1 + spacing * (n - 1))) + ax_new.set_ylabel( + self._trad[axes], + color='green', fontsize=12 + ) + + if self._x is "kp": + if "elevation" in self._y: + logging.info("TODO: kp/elevation") + if "water_elevation" in self._y: + logging.info("TODO: kp/water_elevation") + if "discharge" in self._y: + logging.info("TODO: kp/discharge") + elif self._x is "time": + if "elevation" in self._y: + logging.info("TODO: time/elevation") + if "water_elevation" in self._y: + logging.info("TODO: time/water_elevation") + if "discharge" in self._y: + logging.info("TODO: time/discharge") + + self.canvas.figure.tight_layout() + self.canvas.figure.canvas.draw_idle() + if self.toolbar is not None: + self.toolbar.update() + + @timer + def update(self, reach, profile, timestamp): + if not self._init: + self.draw() + return diff --git a/src/View/Results/CustomPlot/Translate.py b/src/View/Results/CustomPlot/Translate.py index 11c3187e..aee28e0d 100644 --- a/src/View/Results/CustomPlot/Translate.py +++ b/src/View/Results/CustomPlot/Translate.py @@ -27,33 +27,39 @@ class CustomPlotTranslate(ResultsTranslate): def __init__(self): super(CustomPlotTranslate, self).__init__() + # Value type + self._dict['time'] = _translate( "CustomPlot", "Time (sec)" ) - self._dict['kp'] = _translate( "CustomPlot", "Kp (m)" ) - self._dict['elevation'] = _translate( "CustomPlot", "Elevation (m)" ) - self._dict['water_elevation'] = _translate( "CustomPlot", "Water elevation (m)" ) - self._dict['discharge'] = _translate( "CustomPlot", "Discharge (m³/s)" ) + # Unit corresponding long name (plot axes display) + + self._dict['meter'] = _translate( + "CustomPlot", "Elevation (m)" + ) + self._dict['m3s'] = _translate( + "CustomPlot", "Discharge (m³/s)" + ) + # SubDict self._sub_dict["values_x"] = { "kp": self._dict["kp"], "time": self._dict["time"], } - self._sub_dict["values_y"] = { "elevation": self._dict["elevation"], "water_elevation": self._dict["water_elevation"], diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index 353a036c..eb8c5b1d 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -38,7 +38,7 @@ from PyQt5.QtWidgets import ( QFileDialog, QTableView, QAbstractItemView, QUndoStack, QShortcut, QAction, QItemDelegate, QComboBox, QVBoxLayout, QHeaderView, QTabWidget, - QSlider, QLabel, + QSlider, QLabel, QWidget, QGridLayout, ) from View.Tools.Plot.PamhyrCanvas import MplCanvas @@ -51,6 +51,7 @@ from View.Results.PlotH import PlotH from View.Results.PlotSedReach import PlotSedReach from View.Results.PlotSedProfile import PlotSedProfile +from View.Results.CustomPlot.Plot import CustomPlot from View.Results.CustomPlot.CustomPlotValuesSelectionDialog import ( CustomPlotValuesSelectionDialog, ) @@ -91,6 +92,8 @@ class ResultsWindow(PamhyrWindow): parent=parent ) + self._additional_plot = {} + self.setup_table() self.setup_plot() self.setup_slider() @@ -377,6 +380,27 @@ class ResultsWindow(PamhyrWindow): self.update_statusbar() + def _get_current_reach(self): + table = self.find(QTableView, f"tableView_reach") + indexes = table.selectedIndexes() + if len(indexes) == 0: + return 0 + + return indexes[0].row() + + def _get_current_profile(self): + table = self.find(QTableView, f"tableView_profile") + indexes = table.selectedIndexes() + if len(indexes) == 0: + return 0 + + return indexes[0].row() + + def _get_current_timestamp(self): + return self._timestamps[ + self._slider_time.value() + ] + def _set_current_reach(self): table = self.find(QTableView, f"tableView_reach") indexes = table.selectedIndexes() @@ -408,8 +432,53 @@ class ResultsWindow(PamhyrWindow): def _add_custom_plot(self): dlg = CustomPlotValuesSelectionDialog(parent=self) if dlg.exec(): - value = dlg.value - logger.info(value) + x, y = dlg.value + self.create_new_tab_custom_plot(x, y) + + def create_new_tab_custom_plot(self, x:str, y:list): + name = f"{x}: {','.join(y)}" + wname = f"tab_custom_{x}_{y}" + + tab_widget = self.find(QTabWidget, f"tabWidget") + + # This plot already exists + if name in self._additional_plot: + tab_widget.setCurrentWidget( + tab_widget.findChild(QWidget, wname) + ) + return + + widget = QWidget() + grid = QGridLayout() + + widget.setObjectName(wname) + + canvas = MplCanvas(width=5, height=4, dpi=100) + canvas.setObjectName(f"canvas_{x}_{y}") + toolbar = PamhyrPlotToolbar( + canvas, self + ) + + plot = CustomPlot( + x, y, + self._get_current_reach(), + self._get_current_profile(), + self._get_current_timestamp(), + data=self._results, + canvas=canvas, + toolbar=toolbar, + trad=self._trad, + parent=self, + ) + plot.draw() + + # Add plot to additional plot + self._additional_plot[name] = plot + + grid.addWidget(toolbar, 0, 0) + grid.addWidget(canvas, 1, 0) + widget.setLayout(grid) + tab_widget.addTab(widget, name) def _copy(self): logger.info("TODO: copy") From ae40097b5197268c4da7aa129e7f998a643e032a Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Tue, 17 Oct 2023 11:27:00 +0200 Subject: [PATCH 04/10] Results: Fix pep8 format. --- src/View/Results/CustomPlot/Plot.py | 1 - src/View/Results/Window.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index ea1e2001..56fe6a99 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -79,7 +79,6 @@ class CustomPlot(PamhyrPlot): for axes in self._y_axis[1:]: logger.info(axes) ax_new = ax.twinx() - #ax_new.spines['right'].set_position(('axes', 1 + spacing * (n - 1))) ax_new.set_ylabel( self._trad[axes], color='green', fontsize=12 diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index eb8c5b1d..bc6e0500 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -435,7 +435,7 @@ class ResultsWindow(PamhyrWindow): x, y = dlg.value self.create_new_tab_custom_plot(x, y) - def create_new_tab_custom_plot(self, x:str, y:list): + def create_new_tab_custom_plot(self, x: str, y: list): name = f"{x}: {','.join(y)}" wname = f"tab_custom_{x}_{y}" From 4605950b94e91558aaf57bdaf0de40b29f4efd28 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Tue, 17 Oct 2023 17:10:58 +0200 Subject: [PATCH 05/10] Results: CustomPlot: Minor change. --- src/View/Results/CustomPlot/Plot.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index 56fe6a99..384116cd 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -50,6 +50,13 @@ class CustomPlot(PamhyrPlot): self._profile = profile self._timestamp = timestamp + logger.debug( + "Create custom plot for: " + + f"{x} -> {','.join(y)}: " + + f"reach={reach}, profile={profile}, " + + f"timestamp={timestamp}" + ) + self._y_axis = list( set( map( From f73000056c48fad02d79880f153151af580cfe80 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Wed, 18 Oct 2023 10:53:57 +0200 Subject: [PATCH 06/10] Results: CustomPlot: Fix kp / elevation, water_elevation and discharge drawing. --- src/View/Results/CustomPlot/Plot.py | 93 ++++++++++++++++++++---- src/View/Results/CustomPlot/Translate.py | 4 +- src/View/Results/Window.py | 1 - 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index 384116cd..6c6f2ec8 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -23,12 +23,14 @@ from functools import reduce from tools import timer from View.Tools.PamhyrPlot import PamhyrPlot +from View.Results.CustomPlot.Translate import CustomPlotTranslate + logger = logging.getLogger() unit = { - "elevation": "meter", - "water_elevation": "meter", - "discharge": "m3s", + "elevation": "0-meter", + "water_elevation": "0-meter", + "discharge": "1-m3s", } @@ -38,7 +40,7 @@ class CustomPlot(PamhyrPlot): toolbar=None, parent=None): super(CustomPlot, self).__init__( canvas=canvas, - trad=trad, + trad=CustomPlotTranslate(), data=data, toolbar=toolbar, parent=parent @@ -57,10 +59,10 @@ class CustomPlot(PamhyrPlot): f"timestamp={timestamp}" ) - self._y_axis = list( + self._y_axes = sorted( set( map( - lambda y: self._trad[y], + lambda y: unit[y], self._y ) ) @@ -78,26 +80,91 @@ class CustomPlot(PamhyrPlot): self._trad[self._x], color='green', fontsize=12 ) + self.canvas.axes.set_ylabel( - self._trad[self._y_axis[0]], + self._trad[self._y_axes[0]], color='green', fontsize=12 ) - for axes in self._y_axis[1:]: - logger.info(axes) - ax_new = ax.twinx() + self._axes = {} + for axes in self._y_axes[1:]: + ax_new = self.canvas.axes.twinx() ax_new.set_ylabel( self._trad[axes], color='green', fontsize=12 ) + self._axes[axes] = ax_new if self._x is "kp": + results = self.data + reach = results.river.reach(self._reach) + kp = reach.geometry.get_kp() + z_min = reach.geometry.get_z_min() + + self.canvas.axes.set_xlim( + left=min(kp), right=max(kp) + ) + + meter_axes = self.canvas.axes + m3S_axes = self.canvas.axes + if "0-meter" in self._y_axes and "1-m3s" in self._y_axes: + m3s_axes = self._axes["1-m3s"] + if "elevation" in self._y: - logging.info("TODO: kp/elevation") + meter_axes.set_ylim( + bottom=min(0, min(z_min)), + top=max(z_min) + 1 + ) + + meter_axes.plot( + kp, z_min, + color='grey', lw=1. + ) + if "water_elevation" in self._y: - logging.info("TODO: kp/water_elevation") + # Water elevation + water_z = list( + map( + lambda p: p.get_ts_key(self._timestamp, "Z"), + reach.profiles + ) + ) + + + meter_axes.set_ylim( + bottom=min(0, min(z_min)), + top=max(water_z) + 1 + ) + + meter_axes.plot( + kp, water_z, lw=1., + color='b', + ) + + if "elevation" in self._y: + meter_axes.fill_between( + kp, z_min, water_z, + color='blue', alpha=0.5, interpolate=True + ) + if "discharge" in self._y: - logging.info("TODO: kp/discharge") + q = list( + map( + lambda p: p.get_ts_key(self._timestamp, "Q"), + reach.profiles + ) + ) + + m3s_axes.set_ylim( + bottom=min(0, min(q)), + top=max(q) + 1 + ) + + m3s_axes.plot( + kp, q, lw=1., + color='r', + ) + elif self._x is "time": if "elevation" in self._y: logging.info("TODO: time/elevation") diff --git a/src/View/Results/CustomPlot/Translate.py b/src/View/Results/CustomPlot/Translate.py index aee28e0d..555950cd 100644 --- a/src/View/Results/CustomPlot/Translate.py +++ b/src/View/Results/CustomPlot/Translate.py @@ -47,10 +47,10 @@ class CustomPlotTranslate(ResultsTranslate): # Unit corresponding long name (plot axes display) - self._dict['meter'] = _translate( + self._dict['0-meter'] = _translate( "CustomPlot", "Elevation (m)" ) - self._dict['m3s'] = _translate( + self._dict['1-m3s'] = _translate( "CustomPlot", "Discharge (m³/s)" ) diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index bc6e0500..ca53d59d 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -467,7 +467,6 @@ class ResultsWindow(PamhyrWindow): data=self._results, canvas=canvas, toolbar=toolbar, - trad=self._trad, parent=self, ) plot.draw() From 04c8f1ae5f60e98967053ac12efe4b996b1018c6 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Wed, 18 Oct 2023 14:02:55 +0200 Subject: [PATCH 07/10] Results: CustomPlot: Minor change to fix warnings. --- src/View/Results/CustomPlot/Plot.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index 6c6f2ec8..6bfe6aba 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -95,7 +95,7 @@ class CustomPlot(PamhyrPlot): ) self._axes[axes] = ax_new - if self._x is "kp": + if self._x == "kp": results = self.data reach = results.river.reach(self._reach) kp = reach.geometry.get_kp() @@ -130,7 +130,6 @@ class CustomPlot(PamhyrPlot): ) ) - meter_axes.set_ylim( bottom=min(0, min(z_min)), top=max(water_z) + 1 @@ -165,7 +164,7 @@ class CustomPlot(PamhyrPlot): color='r', ) - elif self._x is "time": + elif self._x == "time": if "elevation" in self._y: logging.info("TODO: time/elevation") if "water_elevation" in self._y: From 021971816a1410a1e1e8fb4640ee2d7283e0b0b7 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Fri, 20 Oct 2023 15:09:24 +0200 Subject: [PATCH 08/10] Results: CustomPlot: Implement plot with time on y axes. --- src/View/Results/CustomPlot/Plot.py | 245 +++++++++++++++++++--------- src/View/Results/Window.py | 17 +- 2 files changed, 178 insertions(+), 84 deletions(-) diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index 6bfe6aba..a539112a 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -68,6 +68,151 @@ class CustomPlot(PamhyrPlot): ) ) + self._axes = {} + + def _draw_kp(self): + results = self.data + reach = results.river.reach(self._reach) + kp = reach.geometry.get_kp() + z_min = reach.geometry.get_z_min() + + self.canvas.axes.set_xlim( + left=min(kp), right=max(kp) + ) + + meter_axes = self.canvas.axes + m3S_axes = self.canvas.axes + if "0-meter" in self._y_axes and "1-m3s" in self._y_axes: + m3s_axes = self._axes["1-m3s"] + + if "elevation" in self._y: + meter_axes.set_ylim( + bottom=min(0, min(z_min)), + top=max(z_min) + 1 + ) + + meter_axes.plot( + kp, z_min, + color='grey', lw=1. + ) + + if "water_elevation" in self._y: + # Water elevation + water_z = list( + map( + lambda p: p.get_ts_key(self._timestamp, "Z"), + reach.profiles + ) + ) + + meter_axes.set_ylim( + bottom=min(0, min(z_min)), + top=max(water_z) + 1 + ) + + meter_axes.plot( + kp, water_z, lw=1., + color='b', + ) + + if "elevation" in self._y: + meter_axes.fill_between( + kp, z_min, water_z, + color='blue', alpha=0.5, interpolate=True + ) + + if "discharge" in self._y: + q = list( + map( + lambda p: p.get_ts_key(self._timestamp, "Q"), + reach.profiles + ) + ) + + m3s_axes.set_ylim( + bottom=min(0, min(q)), + top=max(q) + 1 + ) + + m3s_axes.plot( + kp, q, lw=1., + color='r', + ) + + def _draw_time(self): + results = self.data + reach = results.river.reach(self._reach) + profile = reach.profile(self._profile) + + meter_axes = self.canvas.axes + m3S_axes = self.canvas.axes + if "0-meter" in self._y_axes and "1-m3s" in self._y_axes: + m3s_axes = self._axes["1-m3s"] + + ts = list(results.get("timestamps")) + ts.sort() + + self.canvas.axes.set_xlim( + left=min(ts), right=max(ts) + ) + + x = ts + if "elevation" in self._y: + # Z min is constant in time + z_min = profile.geometry.z_min() + ts_z_min = list( + map( + lambda ts: z_min, + ts + ) + ) + + meter_axes.plot( + ts, ts_z_min, + color='grey', lw=1. + ) + + if "water_elevation" in self._y: + # Water elevation + z = profile.get_key("Z") + + meter_axes.set_ylim( + bottom=min(0, min(z)), + top=max(z) + 1 + ) + + meter_axes.plot( + ts, z, lw=1., + color='b', + ) + + if "elevation" in self._y: + z_min = profile.geometry.z_min() + ts_z_min = list( + map( + lambda ts: z_min, + ts + ) + ) + + meter_axes.fill_between( + ts, ts_z_min, z, + color='blue', alpha=0.5, interpolate=True + ) + + if "discharge" in self._y: + q = profile.get_key("Q") + + m3s_axes.set_ylim( + bottom=min(0, min(q)), + top=max(q) + 1 + ) + + m3s_axes.plot( + ts, q, lw=1., + color='r', + ) + @timer def draw(self): self.canvas.axes.cla() @@ -86,8 +231,10 @@ class CustomPlot(PamhyrPlot): color='green', fontsize=12 ) - self._axes = {} for axes in self._y_axes[1:]: + if axes in self._axes: + continue + ax_new = self.canvas.axes.twinx() ax_new.set_ylabel( self._trad[axes], @@ -96,81 +243,9 @@ class CustomPlot(PamhyrPlot): self._axes[axes] = ax_new if self._x == "kp": - results = self.data - reach = results.river.reach(self._reach) - kp = reach.geometry.get_kp() - z_min = reach.geometry.get_z_min() - - self.canvas.axes.set_xlim( - left=min(kp), right=max(kp) - ) - - meter_axes = self.canvas.axes - m3S_axes = self.canvas.axes - if "0-meter" in self._y_axes and "1-m3s" in self._y_axes: - m3s_axes = self._axes["1-m3s"] - - if "elevation" in self._y: - meter_axes.set_ylim( - bottom=min(0, min(z_min)), - top=max(z_min) + 1 - ) - - meter_axes.plot( - kp, z_min, - color='grey', lw=1. - ) - - if "water_elevation" in self._y: - # Water elevation - water_z = list( - map( - lambda p: p.get_ts_key(self._timestamp, "Z"), - reach.profiles - ) - ) - - meter_axes.set_ylim( - bottom=min(0, min(z_min)), - top=max(water_z) + 1 - ) - - meter_axes.plot( - kp, water_z, lw=1., - color='b', - ) - - if "elevation" in self._y: - meter_axes.fill_between( - kp, z_min, water_z, - color='blue', alpha=0.5, interpolate=True - ) - - if "discharge" in self._y: - q = list( - map( - lambda p: p.get_ts_key(self._timestamp, "Q"), - reach.profiles - ) - ) - - m3s_axes.set_ylim( - bottom=min(0, min(q)), - top=max(q) + 1 - ) - - m3s_axes.plot( - kp, q, lw=1., - color='r', - ) - + self._draw_kp() elif self._x == "time": - if "elevation" in self._y: - logging.info("TODO: time/elevation") - if "water_elevation" in self._y: - logging.info("TODO: time/water_elevation") - if "discharge" in self._y: - logging.info("TODO: time/discharge") + self._draw_time() self.canvas.figure.tight_layout() self.canvas.figure.canvas.draw_idle() @@ -178,7 +253,25 @@ class CustomPlot(PamhyrPlot): self.toolbar.update() @timer - def update(self, reach, profile, timestamp): + def update(self): if not self._init: self.draw() return + + def set_reach(self, reach_id): + self._reach = reach_id + self._profile = 0 + + self.update() + + def set_profile(self, profile_id): + self._profile = profile_id + + if self._x != "kp": + self.update() + + def set_timestamp(self, timestamp): + self._timestamp = timestamp + + if self._x != "time": + self.update() diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index ca53d59d..eb6f7aaa 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -345,6 +345,9 @@ class ResultsWindow(PamhyrWindow): self.plot_sed_reach.set_reach(reach_id) self.plot_sed_profile.set_reach(reach_id) + for plot in self._additional_plot: + self._additional_plot[plot].set_reach(reach_id) + self.update_table_selection_reach(reach_id) self.update_table_selection_profile(0) @@ -358,7 +361,11 @@ class ResultsWindow(PamhyrWindow): self.plot_sed_reach.set_profile(profile_id) self.plot_sed_profile.set_profile(profile_id) + for plot in self._additional_plot: + self._additional_plot[plot].set_profile(profile_id) + self.update_table_selection_profile(profile_id) + if timestamp is not None: self.plot_xy.set_timestamp(timestamp) self.plot_ac.set_timestamp(timestamp) @@ -369,14 +376,8 @@ class ResultsWindow(PamhyrWindow): self.plot_sed_reach.set_timestamp(timestamp) self.plot_sed_profile.set_timestamp(timestamp) - self.plot_xy.draw() - self.plot_ac.draw() - self.plot_kpc.draw() - self.plot_h.draw() - - if self._study.river.has_sediment(): - self.plot_sed_reach.draw() - self.plot_sed_profile.draw() + for plot in self._additional_plot: + self._additional_plot[plot].set_timestamp(timestamp) self.update_statusbar() From cdfb867037a39c10400e6e58e66d71f2f47e7561 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Fri, 20 Oct 2023 16:27:07 +0200 Subject: [PATCH 09/10] Results: CustomPlot: Add custom time axes. --- src/View/Results/CustomPlot/Plot.py | 43 +++++++++++++++++++++++++++++ src/View/Results/translate.py | 7 +++++ 2 files changed, 50 insertions(+) diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index a539112a..4712c45b 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -19,6 +19,7 @@ import logging from functools import reduce +from datetime import datetime from tools import timer from View.Tools.PamhyrPlot import PamhyrPlot @@ -139,6 +140,46 @@ class CustomPlot(PamhyrPlot): color='r', ) + def _customize_x_axes_time(self, ts, mode="time"): + # Custom time display + nb = len(ts) + mod = int(nb / 5) + mod = mod if mod > 0 else nb + + fx = list( + map( + lambda x: x[1], + filter( + lambda x: x[0] % mod == 0, + enumerate(ts) + ) + ) + ) + + if mode == "time": + t0 = datetime.fromtimestamp(0) + xt = list( + map( + lambda v: ( + str( + datetime.fromtimestamp(v) - t0 + ).split(",")[0] + .replace("days", self._trad["days"]) + .replace("day", self._trad["day"]) + ), + fx + ) + ) + else: + xt = list( + map( + lambda v: str(datetime.fromtimestamp(v).date()), + fx + ) + ) + + self.canvas.axes.set_xticks(ticks=fx, labels=xt, rotation=45) + def _draw_time(self): results = self.data reach = results.river.reach(self._reach) @@ -213,6 +254,8 @@ class CustomPlot(PamhyrPlot): color='r', ) + self._customize_x_axes_time(ts) + @timer def draw(self): self.canvas.axes.cla() diff --git a/src/View/Results/translate.py b/src/View/Results/translate.py index ae9dcad1..4de61cc7 100644 --- a/src/View/Results/translate.py +++ b/src/View/Results/translate.py @@ -27,6 +27,13 @@ class ResultsTranslate(PamhyrTranslate): def __init__(self): super(ResultsTranslate, self).__init__() + self._dict['day'] = _translate( + "Results", "day" + ) + self._dict['days'] = _translate( + "Results", "days" + ) + self._sub_dict["table_headers_reach"] = { "name": _translate("Results", "Reach name"), } From 32aa5bece59f9bc8a059a2b3dc7ef511ef0fd120 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Fri, 20 Oct 2023 16:48:21 +0200 Subject: [PATCH 10/10] Results: CustomPlot: Add legend and change axes label fontsize for each plot. --- src/View/Geometry/PlotAC.py | 8 +-- src/View/Geometry/PlotKPZ.py | 4 +- src/View/Geometry/PlotXY.py | 4 +- src/View/Results/CustomPlot/Plot.py | 50 +++++++++++++++---- src/View/Results/PlotH.py | 4 +- src/View/Results/PlotSedProfile.py | 4 +- src/View/Results/PlotSedReach.py | 4 +- src/View/Results/PlotXY.py | 4 +- src/View/SedimentLayers/Edit/Plot.py | 2 +- src/View/SedimentLayers/Reach/Plot.py | 4 +- src/View/SedimentLayers/Reach/Profile/Plot.py | 4 +- 11 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/View/Geometry/PlotAC.py b/src/View/Geometry/PlotAC.py index 1d7bf8d8..7cc75184 100644 --- a/src/View/Geometry/PlotAC.py +++ b/src/View/Geometry/PlotAC.py @@ -72,11 +72,11 @@ class PlotAC(PamhyrPlot): self.canvas.axes.set_xlabel( _translate("MainWindow_reach", "Transverse abscissa (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("MainWindow_reach", "Height (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.figure.tight_layout() @@ -176,11 +176,11 @@ class PlotAC(PamhyrPlot): self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5) self.canvas.axes.set_xlabel( _translate("MainWindow_reach", "Abscisse en travers (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("MainWindow_reach", "Cote (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.figure.tight_layout() diff --git a/src/View/Geometry/PlotKPZ.py b/src/View/Geometry/PlotKPZ.py index 41b08a8f..79fbfe05 100644 --- a/src/View/Geometry/PlotKPZ.py +++ b/src/View/Geometry/PlotKPZ.py @@ -64,11 +64,11 @@ class PlotKPZ(PamhyrPlot): self.canvas.axes.set_xlabel( _translate("MainWindow_reach", "Kp (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("MainWindow_reach", "Height (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) kp = self.data.get_kp() diff --git a/src/View/Geometry/PlotXY.py b/src/View/Geometry/PlotXY.py index a851cc82..fcd55ecc 100644 --- a/src/View/Geometry/PlotXY.py +++ b/src/View/Geometry/PlotXY.py @@ -65,11 +65,11 @@ class PlotXY(PamhyrPlot): # Axes self.canvas.axes.set_xlabel( _translate("Geometry", "X (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("Geometry", "Y (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.axis("equal") diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index 4712c45b..9733448f 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -86,16 +86,19 @@ class CustomPlot(PamhyrPlot): if "0-meter" in self._y_axes and "1-m3s" in self._y_axes: m3s_axes = self._axes["1-m3s"] + + lines = {} if "elevation" in self._y: meter_axes.set_ylim( bottom=min(0, min(z_min)), top=max(z_min) + 1 ) - meter_axes.plot( + line = meter_axes.plot( kp, z_min, - color='grey', lw=1. + color='grey', lw=1., ) + lines["elevation"] = line if "water_elevation" in self._y: # Water elevation @@ -111,10 +114,11 @@ class CustomPlot(PamhyrPlot): top=max(water_z) + 1 ) - meter_axes.plot( + line = meter_axes.plot( kp, water_z, lw=1., - color='b', + color='blue', ) + lines["water_elevation"] = line if "elevation" in self._y: meter_axes.fill_between( @@ -135,10 +139,20 @@ class CustomPlot(PamhyrPlot): top=max(q) + 1 ) - m3s_axes.plot( + line = m3s_axes.plot( kp, q, lw=1., color='r', ) + lines["discharge"] = line + + # Legend + lns = reduce( + lambda acc, l: acc + l, + map(lambda l: lines[l], lines), + [] + ) + labs = list(map(lambda l: self._trad[l], lines)) + self.canvas.axes.legend(lns, labs, loc="lower left") def _customize_x_axes_time(self, ts, mode="time"): # Custom time display @@ -198,6 +212,7 @@ class CustomPlot(PamhyrPlot): ) x = ts + lines = {} if "elevation" in self._y: # Z min is constant in time z_min = profile.geometry.z_min() @@ -208,10 +223,11 @@ class CustomPlot(PamhyrPlot): ) ) - meter_axes.plot( + line = meter_axes.plot( ts, ts_z_min, color='grey', lw=1. ) + lines["elevation"] = line if "water_elevation" in self._y: # Water elevation @@ -222,10 +238,11 @@ class CustomPlot(PamhyrPlot): top=max(z) + 1 ) - meter_axes.plot( + line = meter_axes.plot( ts, z, lw=1., color='b', ) + lines["water_elevation"] = line if "elevation" in self._y: z_min = profile.geometry.z_min() @@ -249,13 +266,24 @@ class CustomPlot(PamhyrPlot): top=max(q) + 1 ) - m3s_axes.plot( + line = m3s_axes.plot( ts, q, lw=1., color='r', ) + lines["discharge"] = line + self._customize_x_axes_time(ts) + # Legend + lns = reduce( + lambda acc, l: acc + l, + map(lambda l: lines[l], lines), + [] + ) + labs = list(map(lambda l: self._trad[l], lines)) + self.canvas.axes.legend(lns, labs, loc="lower left") + @timer def draw(self): self.canvas.axes.cla() @@ -266,12 +294,12 @@ class CustomPlot(PamhyrPlot): self.canvas.axes.set_xlabel( self._trad[self._x], - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( self._trad[self._y_axes[0]], - color='green', fontsize=12 + color='green', fontsize=10 ) for axes in self._y_axes[1:]: @@ -281,7 +309,7 @@ class CustomPlot(PamhyrPlot): ax_new = self.canvas.axes.twinx() ax_new.set_ylabel( self._trad[axes], - color='green', fontsize=12 + color='green', fontsize=10 ) self._axes[axes] = ax_new diff --git a/src/View/Results/PlotH.py b/src/View/Results/PlotH.py index dd5a332b..2af2ea41 100644 --- a/src/View/Results/PlotH.py +++ b/src/View/Results/PlotH.py @@ -77,11 +77,11 @@ class PlotH(PamhyrPlot): # Axes self.canvas.axes.set_xlabel( _translate("Results", "Time (s)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("Results", "Discharge (m³/s)"), - color='green', fontsize=12 + color='green', fontsize=10 ) ts = list(self.results.get("timestamps")) diff --git a/src/View/Results/PlotSedProfile.py b/src/View/Results/PlotSedProfile.py index d16fb0b8..013480d9 100644 --- a/src/View/Results/PlotSedProfile.py +++ b/src/View/Results/PlotSedProfile.py @@ -122,11 +122,11 @@ class PlotSedProfile(PamhyrPlot): self.canvas.axes.set_xlabel( _translate("MainWindow_reach", "X (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("MainWindow_reach", "Height (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) x = profile.geometry.get_station() diff --git a/src/View/Results/PlotSedReach.py b/src/View/Results/PlotSedReach.py index 5cdc4ad7..9e49c076 100644 --- a/src/View/Results/PlotSedReach.py +++ b/src/View/Results/PlotSedReach.py @@ -203,11 +203,11 @@ class PlotSedReach(PamhyrPlot): self.canvas.axes.set_xlabel( _translate("MainWindow_reach", "Kp (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("MainWindow_reach", "Height (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) kp = reach.geometry.get_kp() diff --git a/src/View/Results/PlotXY.py b/src/View/Results/PlotXY.py index 5a513322..384e2813 100644 --- a/src/View/Results/PlotXY.py +++ b/src/View/Results/PlotXY.py @@ -78,11 +78,11 @@ class PlotXY(PamhyrPlot): # Axes self.canvas.axes.set_xlabel( _translate("Results", "X (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("Results", "Y (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.axis("equal") diff --git a/src/View/SedimentLayers/Edit/Plot.py b/src/View/SedimentLayers/Edit/Plot.py index 87cfe644..69e58f83 100644 --- a/src/View/SedimentLayers/Edit/Plot.py +++ b/src/View/SedimentLayers/Edit/Plot.py @@ -35,7 +35,7 @@ class Plot(PamhyrPlot): self.canvas.axes.axes.get_xaxis().set_visible(False) self.canvas.axes.set_ylabel( self._trad["height"], - color='green', fontsize=12 + color='green', fontsize=10 ) if self.data is None: diff --git a/src/View/SedimentLayers/Reach/Plot.py b/src/View/SedimentLayers/Reach/Plot.py index 3664081c..1bea651f 100644 --- a/src/View/SedimentLayers/Reach/Plot.py +++ b/src/View/SedimentLayers/Reach/Plot.py @@ -46,11 +46,11 @@ class Plot(PamhyrPlot): self.canvas.axes.set_xlabel( self._trad["kp"], - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( self._trad["height"], - color='green', fontsize=12 + color='green', fontsize=10 ) kp = self.data.get_kp() diff --git a/src/View/SedimentLayers/Reach/Profile/Plot.py b/src/View/SedimentLayers/Reach/Profile/Plot.py index 38adb990..5000ca9b 100644 --- a/src/View/SedimentLayers/Reach/Profile/Plot.py +++ b/src/View/SedimentLayers/Reach/Profile/Plot.py @@ -46,11 +46,11 @@ class Plot(PamhyrPlot): self.canvas.axes.set_xlabel( _translate("MainWindow_reach", "X (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) self.canvas.axes.set_ylabel( _translate("MainWindow_reach", "Height (m)"), - color='green', fontsize=12 + color='green', fontsize=10 ) x = self.data.get_station()