diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py
index 354be9162fda8df2f1788cb2420dde6e86d0572c..3d40fd69ac27f58e525e0d6e64ee6130876d68f5 100644
--- a/src/Model/Geometry/ProfileXYZ.py
+++ b/src/Model/Geometry/ProfileXYZ.py
@@ -489,46 +489,52 @@ class ProfileXYZ(Profile, SQLSubModel):
         #  niveau d'eau pour lequel on a obtenu irg, ird, ptX et ptY
         # ====================================================================
 
-        # initialisation
-        irg = -1
-        ird = -1
+
+        # Get the index of last point with elevation lesser than water
+        # level (for the right and left river side)
+        i_left = -1
+        i_right = -1
 
         for i in range(self.number_points):
             if self.point(i).z <= z:
-                irg = i
+                i_left = i
+                break
 
         for i in reversed(range(self.number_points)):
             if self.point(i).z <= z:
-                ird = i
+                i_right = i
+                break
 
-        # interpolation des points ptX et ptY
-        if (irg < self.number_points - 1):
+        # Interpolate points at river left side
+        if (i_left > 0):
             x = np.interp(
                 z,
-                [self.point(irg).z, self.point(irg + 1).z],
-                [self.point(irg).x, self.point(irg + 1).x]
+                [self.point(i_left).z, self.point(i_left - 1).z],
+                [self.point(i_left).x, self.point(i_left - 1).x]
             )
             y = np.interp(
                 z,
-                [self.point(irg).z, self.point(irg + 1).z],
-                [self.point(irg).y, self.point(irg + 1).y]
+                [self.point(i_left).z, self.point(i_left - 1).z],
+                [self.point(i_left).y, self.point(i_left - 1).y]
             )
-            ptX = PointXYZ(x, y, z)
+            pt_left = PointXYZ(x, y, z)
         else:
-            ptX = self.point(0)
-        if (ird > 0):
+            pt_left = self.point(0)
+
+        # Interpolate points at river right side
+        if (i_right < self.number_points - 1):
             x = np.interp(
                 z,
-                [self.point(ird-1).z, self.point(ird).z],
-                [self.point(ird-1).x, self.point(ird).x]
+                [self.point(i_right).z, self.point(i_right + 1).z],
+                [self.point(i_right).x, self.point(i_right + 1).x]
             )
             y = np.interp(
                 z,
-                [self.point(ird).z, self.point(ird - 1).z],
-                [self.point(ird).y, self.point(ird - 1).y]
+                [self.point(i_right).z, self.point(i_right + 1).z],
+                [self.point(i_right).y, self.point(i_right + 1).y]
             )
-            ptY = PointXYZ(x, y, z)
+            pt_right = PointXYZ(x, y, z)
         else:
-            ptY = self.point(self.number_points - 1)
+            pt_right = self.point(self.number_points - 1)
 
-        return ptX, ptY
+        return pt_left, pt_right
diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py
index 83e6e5124040c41cc7f35edb2c6705133b80b4c3..dbd22a626c89cbf5ea78ecf8b49af51dd59585f0 100644
--- a/src/Solver/Mage.py
+++ b/src/Solver/Mage.py
@@ -1023,9 +1023,12 @@ class Mage8(Mage):
                         reach.set(ri, timestamp, key, d)
                         if key == "Z":
                             profile = reach.profile(ri)
-                            ptX, ptY = profile.geometry.get_water_limits(d)
-                            reach.set(ri, timestamp, "ptX", ptX)
-                            reach.set(ri, timestamp, "ptY", ptY)
+                            limits = profile.geometry.get_water_limits(d)
+                            reach.set(
+                                ri, timestamp,
+                                "water_limits",
+                                limits
+                            )
 
                 endline()
                 end = newline().size <= 0
diff --git a/src/View/Results/PlotKPC.py b/src/View/Results/PlotKPC.py
index 34a4ca5eb9b394b27873f68eed49130a401407ef..458e60485689e7ce7a6a275a44a01e1718e5e116 100644
--- a/src/View/Results/PlotKPC.py
+++ b/src/View/Results/PlotKPC.py
@@ -73,7 +73,6 @@ class PlotKPC(PamhyrPlot):
 
         reach = self.results.river.reach(self._current_reach_id)
 
-
         self.draw_bottom(reach)
         self.draw_water_elevation(reach)
         self.draw_water_elevation_max(reach)
diff --git a/src/View/Results/PlotXY.py b/src/View/Results/PlotXY.py
index 72733c52cfe0e25763635cf0c3f0bc2a462bcf92..d74c1326403307230e01dc48fc3fe3577694ebcd 100644
--- a/src/View/Results/PlotXY.py
+++ b/src/View/Results/PlotXY.py
@@ -44,15 +44,20 @@ class PlotXY(PamhyrPlot):
             parent=parent
         )
 
-        self.display_current = display_current
-
         self.line_xy = []
         self.line_gl = []
+        self.overflow = []
 
-        self._current_timestamp = max(results.get("timestamps"))
+        self._timestamps = results.get("timestamps")
+        self._current_timestamp = max(self._timestamps)
         self._current_reach_id = reach_id
         self._current_profile_id = profile_id
 
+        self.label_x = _translate("Results", "X (m)")
+        self.label_y = _translate("Results", "Y (m)")
+
+        self._isometric_axis = True
+
     @property
     def results(self):
         return self.data
@@ -64,53 +69,41 @@ class PlotXY(PamhyrPlot):
 
     @timer
     def draw(self, highlight=None):
-        self.canvas.axes.cla()
-        self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5)
+        self.init_axes()
 
         if self.results is None:
             return
 
         reach = self.results.river.reach(self._current_reach_id)
 
+        self.draw_profiles(reach)
+        self.draw_water_elevation(reach)
+        self.draw_water_elevation_max(reach)
+        self.draw_guide_lines(reach)
+        self.draw_current(reach)
+
+        self.idle()
+        self._init = True
+
+    def draw_profiles(self, reach):
         if reach.geometry.number_profiles == 0:
             self._init = False
             return
 
-        kp_min, kp_max = (-1, -1)
-        if highlight is not None:
-            kp_min, kp_max = highlight
-
-        # Axes
-        self.canvas.axes.set_xlabel(
-            _translate("Results", "X (m)"),
-            color='black', fontsize=10
-        )
-        self.canvas.axes.set_ylabel(
-            _translate("Results", "Y (m)"),
-            color='black', fontsize=10
-        )
-        self.canvas.axes.axis("equal")
-
-        kp = reach.geometry.get_kp()
-        self.canvas.axes.set_xlim(
-            left=min(kp), right=max(kp)
-        )
-
-        # Draw line for each profile
         self.line_xy = [
             self.canvas.axes.plot(
-                x, y, lw=1.,
-                color='b' if kp_min <= kp <= kp_max else 'grey',
-                markersize=3, marker='+'
+                x, y,
+                color=self.color_plot_river_bottom,
+                **self.plot_default_kargs
             )
             for x, y, kp in zip(
                 reach.geometry.get_x(),
                 reach.geometry.get_y(),
-                kp
+                reach.geometry.get_kp()
             )
         ]
 
-        # Guide lines
+    def draw_guide_lines(self, reach):
         x_complete = reach.geometry.get_guidelines_x()
         y_complete = reach.geometry.get_guidelines_y()
 
@@ -121,35 +114,106 @@ class PlotXY(PamhyrPlot):
             for x, y in zip(x_complete, y_complete)
         ]
 
-        if self.display_current:
-            # Current profile
-            profile = reach.profile(self._current_profile_id).geometry
+    def draw_current(self, reach):
+        profile = reach.profile(self._current_profile_id)
+
+        self.plot_selected, = self.canvas.axes.plot(
+            profile.geometry.x(),
+            profile.geometry.y(),
+            color=self.color_plot,
+            **self.plot_default_kargs
+        )
+
+
+    def draw_water_elevation_max(self, reach):
+        l_x, l_y, r_x, r_y = [], [], [], []
+        overflow = []
 
-            self.plot_selected, = self.canvas.axes.plot(
-                profile.x(),
-                profile.y(),
-                lw=1., markersize=3,
-                color="r", marker='+'
+        for profile in reach.profiles:
+            z_max = max(profile.get_key("Z"))
+            z_max_ts = 0
+            for ts in self._timestamps:
+                z = profile.get_ts_key(ts, "Z")
+                if z == z_max:
+                    z_max_ts = ts
+                    break
+
+            pt_left, pt_right = profile.get_ts_key(z_max_ts, "water_limits")
+
+            l_x.append(pt_left.x)
+            l_y.append(pt_left.y)
+            r_x.append(pt_right.x)
+            r_y.append(pt_right.y)
+
+            if self.is_overflow_point(profile, pt_left):
+                overflow.append(pt_left)
+
+            if self.is_overflow_point(profile, pt_right):
+                overflow.append(pt_right)
+
+        self.water_max_left = self.canvas.axes.plot(
+            l_x, l_y,
+            color=self.color_plot_river_water,
+            linestyle='dotted',
+            lw=1.,
+        )
+
+        self.water_max_right = self.canvas.axes.plot(
+            r_x, r_y,
+            color=self.color_plot_river_water,
+            linestyle='dotted',
+            lw=1.,
+        )
+
+        for p in overflow:
+            self.canvas.axes.plot(
+                p.x, p.y,
+                lw=1.,
+                color=self.color_plot,
+                markersize=3,
+                marker='x'
+            )
+
+
+    def is_overflow_point(self, profile, point):
+            left_limit = profile.geometry.point(0)
+            right_limit = profile.geometry.point(
+                profile.geometry.number_points - 1
+            )
+
+            return (
+                point == left_limit
+                or point == right_limit
+            )
+
+
+    def draw_water_elevation(self, reach):
+        reach = self.results.river.reach(self._current_reach_id)
+        poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], []
+
+        for profile in reach.profiles:
+            water_z = profile.get_ts_key(
+                self._current_timestamp, "Z"
+            )
+            pt_left, pt_right = profile.get_ts_key(
+                self._current_timestamp,
+                "water_limits"
             )
-            self.plot_selected.set_visible(True)
 
-        poly_x = [0]
-        poly_y = [0]
+            poly_l_x.append(pt_left.x)
+            poly_l_y.append(pt_left.y)
+            poly_r_x.append(pt_right.x)
+            poly_r_y.append(pt_right.y)
 
-        self.fill = self.canvas.axes.fill(
+        poly_x = poly_l_x + list(reversed(poly_r_x))
+        poly_y = poly_l_y + list(reversed(poly_r_y))
+
+        self.water_fill = self.canvas.axes.fill(
             poly_x, poly_y,
-            color='skyblue',
+            color=self.color_plot_river_water_zone,
             alpha=0.7
         )
 
-        # self.canvas.axes.autoscale_view(True, True, True)
-        # self.canvas.axes.autoscale()
-        self.canvas.figure.tight_layout()
-        self.canvas.figure.canvas.draw_idle()
-        if self.toolbar is not None:
-            self.toolbar.update()
-        self.update()
-
     def set_reach(self, reach_id):
         self._current_reach_id = reach_id
         self._current_profile_id = 0
@@ -158,63 +222,91 @@ class PlotXY(PamhyrPlot):
     def set_profile(self, profile_id):
         self._current_profile_id = profile_id
         self.update_profile()
+        self.update_idle()
 
     def set_timestamp(self, timestamp):
         self._current_timestamp = timestamp
-        self.update_poly()
+        self.update()
 
-    def update_profile(self):
+    def update(self):
+        if not self._init:
+            self.draw()
 
-        reach = self.results.river.reach(self._current_reach_id)
-        if self.display_current:
-            # Current profile
-            profile = reach.profile(self._current_profile_id).geometry
+        self.update_water_elevation()
+        self.update_water_elevation_overflow()
+
+        self.update_idle()
 
-            self.plot_selected.set_data(profile.x(), profile.y())
-            self.plot_selected.set_visible(True)
-        self.canvas.draw_idle()
+    def update_profile(self):
+        reach = self.results.river.reach(self._current_reach_id)
+        profile = reach.profile(self._current_profile_id)
 
-    def update_poly(self):
+        self.plot_selected.set_data(
+            profile.geometry.x(),
+            profile.geometry.y()
+        )
 
+    def update_water_elevation(self):
         reach = self.results.river.reach(self._current_reach_id)
-        profile = reach.profile(self._current_profile_id).geometry
+        poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], []
 
-        # Display water
-        poly_l_x = []
-        poly_l_y = []
-        poly_r_x = []
-        poly_r_y = []
         for profile in reach.profiles:
             water_z = profile.get_ts_key(
                 self._current_timestamp, "Z"
             )
-            ptX = profile.get_ts_key(
-                self._current_timestamp, "ptX"
-            )
-            ptY = profile.get_ts_key(
-                self._current_timestamp, "ptY"
+            pt_left, pt_right = profile.get_ts_key(
+                self._current_timestamp,
+                "water_limits"
             )
 
-            poly_l_x.append(ptX.x)
-            poly_l_y.append(ptX.y)
-            poly_r_x.append(ptY.x)
-            poly_r_y.append(ptY.y)
-
-            # self.canvas.axes.plot(
-            #     x, y, lw=1.,
-            #     color='b',
-            #     markersize=1,
-            #     marker='o'
-            # )
+            poly_l_x.append(pt_left.x)
+            poly_l_y.append(pt_left.y)
+            poly_r_x.append(pt_right.x)
+            poly_r_y.append(pt_right.y)
 
         poly_x = poly_l_x + list(reversed(poly_r_x))
         poly_y = poly_l_y + list(reversed(poly_r_y))
+
         poly = []
         for i in range(len(poly_x)):
             poly.append([poly_x[i], poly_y[i]])
-        self.fill[0].set_xy(poly)
-        self.canvas.draw_idle()
 
-    def update(self):
-        self.update_profile()
-        self.update_poly()
+        self.water_fill[0].set_xy(poly)
+
+    def update_water_elevation_overflow(self):
+        reach = self.results.river.reach(self._current_reach_id)
+        profile = reach.profile(self._current_profile_id)
+
+        overflow = []
+
+        for profile in reach.profiles:
+            pt_left, pt_right = profile.get_ts_key(
+                self._current_timestamp,
+                "water_limits"
+            )
+
+            left_limit = profile.geometry.point(0)
+            right_limit = profile.geometry.point(
+                profile.geometry.number_points - 1
+            )
+
+            if pt_left == left_limit:
+                overflow.append(pt_left)
+
+            if pt_right == right_limit:
+                overflow.append(pt_right)
+
+        for plot in self.overflow:
+            plot[0].remove()
+            del plot[0]
+        self.overflow = []
+
+        for p in overflow:
+            plot = self.canvas.axes.plot(
+                p.x, p.y,
+                lw=1.,
+                color=self.color_plot,
+                markersize=3,
+                marker='o'
+            )
+            self.overflow.append(plot)