diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py
index 2e3a6b8098730e948b2eb8c306429d5a0f950084..0839f928f4479fe4bc09b93610ee9f4e1be1cfb2 100644
--- a/src/Model/Geometry/Reach.py
+++ b/src/Model/Geometry/Reach.py
@@ -111,6 +111,19 @@ class Reach:
         self._profiles.pop(index)
         self._update_profile_numbers()
 
+    def move_up_profile(self, index: int):
+        if index < len(self.profiles):
+            next = index - 1
+
+            p = self._profiles
+            p[index], p[next] = p[next], p[index]
+
+    def move_down_profile(self, index: int):
+        if index >= 0:
+            prev = index + 1
+
+            p = self._profiles
+            p[index], p[prev] = p[prev], p[index]
 
     def get_x(self):
         return [profile.x() for profile in self.profiles]
diff --git a/src/View/Geometry/GeometryWindow.py b/src/View/Geometry/GeometryWindow.py
index 9a339bdfeb4fce48fd91a2d6696b0f75572ee481..8b7922197c0114288b626044e5caa67dc9edc54a 100644
--- a/src/View/Geometry/GeometryWindow.py
+++ b/src/View/Geometry/GeometryWindow.py
@@ -396,69 +396,21 @@ class GeometryWindow(QMainWindow, WindowToolKit):
         self.select_current_profile()
         self.changed_slider_value()
 
-        self.update_plot_kpc()
-        self.update_plot_ac(self.index_selected_row())
-
     def sort_descending(self):
         self._tablemodel.sort_profiles(False)
 
         self.select_current_profile()
         self.changed_slider_value()
 
-        self.update_plot_kpc()
-        self.update_plot_ac(self.index_selected_row())
-
     def move_row_down(self):
         row = self.index_selected_row()
-
-        if row < self._tablemodel.rowCount() - 1:
-            self._tablemodel.moveRowDown(row)
-            self.update_plot_ac(row + 1)
-            self.ui.canvas_3.axes.relim()
-            self.ui.canvas_3.axes.autoscale_view()
-
-            if row < self._tablemodel.rowCount() - 2:
-                self.select_before_plot_selected_1(row)
-                self.select_after_plot_selected_1(row + 2)
-                self.select_before_plot_selected_2(row)
-                self.select_after_plot_selected_2(row + 2)
-
-            if row == self._tablemodel.rowCount() - 2:
-                self.select_before_plot_selected_1(self._tablemodel.rowCount() - 2)
-                self.after_plot_selected_1.set_visible(False)
-                self.select_before_plot_selected_2(self._tablemodel.rowCount() - 2)
-                self.after_plot_selected_2.set_visible(False)
-
-            self.update_plot_kpc()
+        self._tablemodel.move_row_down(row)
+        self.select_current_profile()
 
     def move_row_up(self):
         row = self.index_selected_row()
-
-        if 0 < row <= self._tablemodel.rowCount() - 1:
-            self._tablemodel.moveRowUp(row)
-
-            if row == 1:
-                self.select_after_plot_selected_1(row)
-                self.before_plot_selected_1.set_visible(False)
-                self.select_after_plot_selected_2(row)
-                self.before_plot_selected_2.set_visible(False)
-
-            elif row == self._tablemodel.rowCount() - 1:
-                self.select_before_plot_selected_1(row - 2)
-                self.select_after_plot_selected_1(row)
-                self.select_before_plot_selected_2(row - 2)
-                self.select_after_plot_selected_2(row)
-
-            else:
-                self.select_before_plot_selected_1(row - 2)
-                self.select_after_plot_selected_1(row)
-                self.select_before_plot_selected_2(row - 2)
-                self.select_after_plot_selected_2(row)
-
-            self.update_plot_kpc()
-            self.update_plot_ac(row - 1)
-            self.ui.canvas_3.axes.relim()
-            self.ui.canvas_3.axes.autoscale_view()
+        self._tablemodel.move_row_up(row)
+        self.select_current_profile()
 
     def handleSave(self):
         options = QFileDialog.Options()
diff --git a/src/View/Geometry/ReachUndoCommand.py b/src/View/Geometry/ReachUndoCommand.py
index 92764f67a6f2864dc21fdb85179737f9d5b5967e..efedd04702fa61c38a86ffeb38cd6a4d03e76269 100644
--- a/src/View/Geometry/ReachUndoCommand.py
+++ b/src/View/Geometry/ReachUndoCommand.py
@@ -83,3 +83,24 @@ class SortCommand(QUndoCommand):
 
     def redo(self):
         self._reach.sort(self._reverse)
+
+
+class MoveCommand(QUndoCommand):
+    def __init__(self, reach, up, i):
+        QUndoCommand.__init__(self)
+
+        self._reach = reach
+        self._up = up == "up"
+        self._i = i
+
+    def undo(self):
+        if self._up:
+            self._reach.move_up_profile(self._i)
+        else:
+            self._reach.move_down_profile(self._i)
+
+    def redo(self):
+        if self._up:
+            self._reach.move_up_profile(self._i)
+        else:
+            self._reach.move_down_profile(self._i)
diff --git a/src/View/Geometry/qtableview_reach.py b/src/View/Geometry/qtableview_reach.py
index 210e336b012cce16afd647d0c49e063d8d1830a4..d6e9321df1d7df2cc24767120a157d18a40dff03 100644
--- a/src/View/Geometry/qtableview_reach.py
+++ b/src/View/Geometry/qtableview_reach.py
@@ -174,20 +174,37 @@ class PandasModelEditable(QAbstractTableModel):
         self.layoutAboutToBeChanged.emit()
         self.layoutChanged.emit()
 
-    def moveRowDown(self, row_to_move, parent=QModelIndex()):
-        target = row_to_move + 2
-        self.beginMoveRows(parent, row_to_move, row_to_move, parent, target)
 
-        self._reach.move_down_profile(row_to_move)
+    def move_row_up(self, row, parent=QModelIndex()):
+        target = row + 2
+
+        if row <= 0:
+            return
+
+        self.beginMoveRows(parent, row - 1, row - 1, parent, target)
+
+        self._undo_stack.push(
+            MoveCommand(
+                self._reach, "up", row
+            )
+        )
 
         self.endMoveRows()
         self.layoutChanged.emit()
 
-    def moveRowUp(self, row_to_move, parent=QModelIndex()):
-        target = row_to_move + 1
-        self.beginMoveRows(parent, row_to_move - 1, row_to_move - 1, parent, target)
+    def move_row_down(self, row, parent=QModelIndex()):
+        target = row
 
-        self._reach.move_up_profile(row_to_move)
+        if row > self._reach.number_profiles:
+            return
+
+        self.beginMoveRows(parent, row + 1, row + 1, parent, target)
+
+        self._undo_stack.push(
+            MoveCommand(
+                self._reach, "down", row
+            )
+        )
 
         self.endMoveRows()
         self.layoutChanged.emit()