diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py index e45d9ea116637b42b5ebf78c35c983a7d8ab193c..b0107a1d77f6dc4eb98bebdc2c7043b5567b88ff 100644 --- a/src/View/Results/CustomPlot/Plot.py +++ b/src/View/Results/CustomPlot/Plot.py @@ -32,6 +32,7 @@ unit = { "elevation": "0-meter", "water_elevation": "0-meter", "discharge": "1-m3s", + "velocity": "2-ms", } @@ -76,18 +77,40 @@ class CustomPlot(PamhyrPlot): reach = results.river.reach(self._reach) rk = reach.geometry.get_rk() z_min = reach.geometry.get_z_min() + q = list( + map( + lambda p: p.get_ts_key(self._timestamp, "Q"), + reach.profiles + ) + ) + z = list( + map( + lambda p: p.get_ts_key(self._timestamp, "Z"), + reach.profiles + ) + ) # self.canvas.axes.set_xlim( # left=min(rk), right=max(rk) # ) meter_axes = self.canvas.axes - m3S_axes = self.canvas.axes + #m3s_axes = meter_axes.twinx() + #ms_axes = meter_axes.twinx() + shift = 0 if "0-meter" in self._y_axes and "1-m3s" in self._y_axes: m3s_axes = self._axes["1-m3s"] + m3s_axes.spines['right'].set_position(('outward', shift)) + shift += 60 + + if "0-meter" in self._y_axes and "2-ms" in self._y_axes: + ms_axes = self._axes["2-ms"] + ms_axes.spines['right'].set_position(('outward', shift)) + shift += 60 lines = {} if "elevation" in self._y: + # meter_axes.set_ylim( # bottom=min(0, min(z_min)), # top=max(z_min) + 1 @@ -100,38 +123,25 @@ class CustomPlot(PamhyrPlot): lines["elevation"] = line 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 + # top=max(z) + 1 # ) line = meter_axes.plot( - rk, water_z, lw=1., + rk, z, lw=1., color='blue', ) lines["water_elevation"] = line if "elevation" in self._y: meter_axes.fill_between( - rk, z_min, water_z, + rk, z_min, 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)), @@ -144,6 +154,27 @@ class CustomPlot(PamhyrPlot): ) lines["discharge"] = line + if "velocity" in self._y: + v = list( + map( + lambda p: p.geometry.speed( + p.get_ts_key(self._timestamp, "Q"), + p.get_ts_key(self._timestamp, "Z")), + reach.profiles + ) + ) + + # m3s_axes.set_ylim( + # bottom=min(0, min(q)), + # top=max(q) + 1 + # ) + + line = ms_axes.plot( + rk, v, lw=1., + color='g', + ) + lines["velocity"] = line + # Legend lns = reduce( lambda acc, line: acc + line, @@ -151,7 +182,7 @@ class CustomPlot(PamhyrPlot): [] ) labs = list(map(lambda line: self._trad[line], lines)) - self.canvas.axes.legend(lns, labs, loc="lower left") + self.canvas.axes.legend(lns, labs, loc="best") def _customize_x_axes_time(self, ts, mode="time"): # Custom time display @@ -199,13 +230,25 @@ class CustomPlot(PamhyrPlot): profile = reach.profile(self._profile) meter_axes = self.canvas.axes - m3S_axes = self.canvas.axes + #m3s_axes = meter_axes.twinx() + #ms_axes = meter_axes.twinx() + shift = 0 if "0-meter" in self._y_axes and "1-m3s" in self._y_axes: m3s_axes = self._axes["1-m3s"] + m3s_axes.spines['right'].set_position(('outward', shift)) + shift += 60 + + if "0-meter" in self._y_axes and "2-ms" in self._y_axes: + ms_axes = self._axes["2-ms"] + ms_axes.spines['right'].set_position(('outward', shift)) + shift += 60 ts = list(results.get("timestamps")) ts.sort() + q = profile.get_key("Q") + z = profile.get_key("Z") + # self.canvas.axes.set_xlim( # left=min(ts), right=max(ts) # ) @@ -229,8 +272,6 @@ class CustomPlot(PamhyrPlot): lines["elevation"] = line if "water_elevation" in self._y: - # Water elevation - z = profile.get_key("Z") # meter_axes.set_ylim( # bottom=min(0, min(z)), @@ -258,7 +299,6 @@ class CustomPlot(PamhyrPlot): ) if "discharge" in self._y: - q = profile.get_key("Q") # m3s_axes.set_ylim( # bottom=min(0, min(q)), @@ -271,6 +311,26 @@ class CustomPlot(PamhyrPlot): ) lines["discharge"] = line + if "velocity" in self._y: + + v = list( + map( + lambda q, z: profile.geometry.speed(q, z), + q, z + ) + ) + + # ms_axes.set_ylim( + # bottom=min(0, min(q)), + # top=max(q) + 1 + # ) + + line = ms_axes.plot( + ts, v, lw=1., + color='g', + ) + lines["velocity"] = line + self._customize_x_axes_time(ts) # Legend @@ -280,7 +340,7 @@ class CustomPlot(PamhyrPlot): [] ) labs = list(map(lambda line: self._trad[line], lines)) - self.canvas.axes.legend(lns, labs, loc="lower left") + self.canvas.axes.legend(lns, labs, loc="best") @timer def draw(self): @@ -317,7 +377,7 @@ class CustomPlot(PamhyrPlot): elif self._x == "time": self._draw_time() - self.canvas.figure.tight_layout() + #self.canvas.figure.tight_layout() self.canvas.figure.canvas.draw_idle() if self.toolbar is not None: self.toolbar.update() diff --git a/src/View/Results/CustomPlot/Translate.py b/src/View/Results/CustomPlot/Translate.py index c32d2b588d98d0a93936d8f42b43c0920aa05050..ebbea20a629d816dc17de205d7cca2ccb5e87a06 100644 --- a/src/View/Results/CustomPlot/Translate.py +++ b/src/View/Results/CustomPlot/Translate.py @@ -40,6 +40,7 @@ class CustomPlotTranslate(ResultsTranslate): self._dict['elevation'] = _translate( "CustomPlot", "Bed elevation (m)" ) + self._dict['velocity'] = self._dict["unit_speed"] # Unit corresponding long name (plot axes display) @@ -47,6 +48,7 @@ class CustomPlotTranslate(ResultsTranslate): "CustomPlot", "Bed elevation (m)" ) self._dict['1-m3s'] = self._dict["unit_discharge"] + self._dict['2-ms'] = self._dict["unit_speed"] # SubDict @@ -58,4 +60,5 @@ class CustomPlotTranslate(ResultsTranslate): "elevation": self._dict["elevation"], "water_elevation": self._dict["water_elevation"], "discharge": self._dict["discharge"], + "velocity": self._dict["velocity"], } diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index 146847ae3787ebf7216edd75d8adfbe629621355..3577b21aac5ad93a43cb6d228f90d7ada33934fa 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -40,7 +40,7 @@ from PyQt5.QtWidgets import ( QFileDialog, QTableView, QAbstractItemView, QUndoStack, QShortcut, QAction, QItemDelegate, QComboBox, QVBoxLayout, QHeaderView, QTabWidget, - QSlider, QLabel, QWidget, QGridLayout, + QSlider, QLabel, QWidget, QGridLayout, QTabBar ) from View.Tools.Plot.PamhyrCanvas import MplCanvas @@ -158,6 +158,12 @@ class ResultsWindow(PamhyrWindow): def setup_plots(self): self.canvas = MplCanvas(width=5, height=4, dpi=100) + tab_widget = self.find(QTabWidget, f"tabWidget") + tab_widget.setTabsClosable(True) + tab_widget.tabCloseRequested.connect(self.delete_tab) + tab_widget.tabBar().setTabButton(0, QTabBar.RightSide, None) + tab_widget.tabBar().setTabButton(1, QTabBar.RightSide, None) + tab_widget.tabBar().setTabButton(2, QTabBar.RightSide, None) self.canvas.setObjectName("canvas") self.toolbar = PamhyrPlotToolbar( self.canvas, self, items=[ @@ -661,3 +667,7 @@ class ResultsWindow(PamhyrWindow): def export_current_to(self, directory): reach = self._results.river.reachs[self._get_current_reach()] self.export_reach(reach, directory, [self._get_current_timestamp()]) + + def delete_tab(self, index): + tab_widget = self.find(QTabWidget, f"tabWidget") + tab_widget.removeTab(index) diff --git a/src/View/Tools/PamhyrPlot.py b/src/View/Tools/PamhyrPlot.py index 761592053a16e73105e367fe3c6155ebb1bd0f1c..b893db844da529002432d83d58d5636d9e9ffdf4 100644 --- a/src/View/Tools/PamhyrPlot.py +++ b/src/View/Tools/PamhyrPlot.py @@ -192,7 +192,6 @@ class PamhyrPlot(APlot): self.canvas.axes.autoscale_view(True, True, True) self.canvas.axes.autoscale() - self.canvas.figure.tight_layout() self.canvas.figure.canvas.draw_idle() self.toolbar_update() @@ -205,7 +204,6 @@ class PamhyrPlot(APlot): self.canvas.axes.autoscale_view(True, True, True) self.canvas.axes.autoscale() - self.canvas.figure.tight_layout() self.canvas.figure.canvas.draw_idle() self.toolbar_update() diff --git a/src/View/Tools/Plot/PamhyrCanvas.py b/src/View/Tools/Plot/PamhyrCanvas.py index 1694d1fdbb4f64dea99b24e9616709a21c43856b..2101aa60945580c5fbcb7cc184087f677643a421 100644 --- a/src/View/Tools/Plot/PamhyrCanvas.py +++ b/src/View/Tools/Plot/PamhyrCanvas.py @@ -23,7 +23,7 @@ class MplCanvas(FigureCanvasQTAgg): fig = Figure( figsize=(width, height), dpi=dpi, - layout='tight', + layout='constrained', ) super(MplCanvas, self).__init__(fig) @@ -36,7 +36,6 @@ class MplCanvas(FigureCanvasQTAgg): self.axes.yaxis.tick_left() self.axes.xaxis.tick_bottom() self.axes.spines[['top', 'right']].set_color('none') - self.figure.tight_layout() self.add_arrows() def add_arrows(self): diff --git a/src/View/ui/Results.ui b/src/View/ui/Results.ui index 9bbd45806abb1ea184be5f7075a64dc2e4305b97..479f5f0520f22dcb60624358d7e0393b5744a997 100644 --- a/src/View/ui/Results.ui +++ b/src/View/ui/Results.ui @@ -145,7 +145,10 @@ <item row="0" column="0"> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> - <number>1</number> + <number>0</number> + </property> + <property name="tabsClosable"> + <bool>true</bool> </property> <widget class="QWidget" name="tab_4"> <attribute name="title">