diff --git a/sohstationviewer/database/soh.db b/sohstationviewer/database/soh.db
index 4b0ea0a9262a978f1b1e72bcb45b4774afb180d5..90430cd3be7ab2b25781a5f0d15c3f640e62b3a2 100755
Binary files a/sohstationviewer/database/soh.db and b/sohstationviewer/database/soh.db differ
diff --git a/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py b/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
index 0e36e7ab4e08bee2f3caba711566357eec7473f0..f8cec92810a379ae2c31ed608f884c90b56af1be 100644
--- a/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
+++ b/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
@@ -109,7 +109,9 @@ class MultiThreadedPlottingWidget(PlottingWidget):
 
     def create_plotting_channel_processors(
             self, plotting_data: Dict,
-            need_db_info: bool = False) -> None:
+            need_db_info: bool = False,
+            need_move_channel: bool = False
+    ) -> None:
         """
         Create a data processor for each channel data in the order of
             pref_order. If pref_order isn't given, process in order of
@@ -117,6 +119,8 @@ class MultiThreadedPlottingWidget(PlottingWidget):
 
         :param plotting_data: dict of data by chan_id
         :param need_db_info: flag to get db info
+        :param need_move_channel: flag to call
+            move_soh_channels_with_link_to_the_end()
         """
         chan_order = self.pref_order if self.pref_order \
             else sorted(list(plotting_data.keys()))
@@ -151,7 +155,8 @@ class MultiThreadedPlottingWidget(PlottingWidget):
                    f"{', '.join( not_plot_chans)}")
             self.processing_log.append((msg, LogType.WARNING))
 
-        self.move_soh_channels_with_link_to_the_end()
+        if need_move_channel:
+            self.move_soh_channels_with_link_to_the_end(chan_order)
 
         for chan_id in chan_order:
             if 'chan_db_info' not in plotting_data[chan_id]:
@@ -165,24 +170,11 @@ class MultiThreadedPlottingWidget(PlottingWidget):
             channel_processor.finished.connect(self.process_channel)
             channel_processor.stopped.connect(self.has_stopped)
 
-    def move_soh_channels_with_link_to_the_end(self):
+    def move_soh_channels_with_link_to_the_end(self, chan_order):
         """
-        In order to plot a channel (channel A) that is linked with another
-        channel (channel B), we need to plot B before we plot A. Because the
-        order of the channel in the data is not predetermined, we need to
-        manually move A to the end of the data set. This is, of course,
-        assuming that channel link is at most one level deep.
+        This only need for soh channels
         """
-        channels_to_move = []
-        for channel, chan_data in self.plotting_data1.items():
-            try:
-                linked_channel = chan_data['chan_db_info']['linkedChan']
-                if linked_channel not in ['', 'None', None]:
-                    channels_to_move.append(channel)
-            except KeyError:
-                continue
-        for channel in channels_to_move:
-            self.plotting_data1[channel] = self.plotting_data1.pop(channel)
+        pass
 
     def plot_channels(self, d_obj, key, start_tm, end_tm, time_ticks_total,
                       pref_order=[]):
@@ -211,8 +203,10 @@ class MultiThreadedPlottingWidget(PlottingWidget):
                 self.finished.emit()
                 return
 
-            self.create_plotting_channel_processors(self.plotting_data1, True)
-            self.create_plotting_channel_processors(self.plotting_data2, True)
+            self.create_plotting_channel_processors(
+                self.plotting_data1, True, True)
+            self.create_plotting_channel_processors(
+                self.plotting_data2, True)
 
             self.process_channel()
 
diff --git a/sohstationviewer/view/plotting/plotting_widget/plotting.py b/sohstationviewer/view/plotting/plotting_widget/plotting.py
index 1a169ac683cf9f2627f65f06bfc4b6cb6a07130b..133699e98afd2f0b156fe5bf793b3ec761c494c0 100644
--- a/sohstationviewer/view/plotting/plotting_widget/plotting.py
+++ b/sohstationviewer/view/plotting/plotting_widget/plotting.py
@@ -280,8 +280,10 @@ class Plotting:
 
         if chan_id == 'GPS Lk/Unlk':
             sample_no_list = []
-            sample_no_list.append(np.where(y_list[0] == -1)[0].size)
-            sample_no_list.append(np.where(y_list[0] == 1)[0].size)
+            ax.x_bottom = x_list[0][np.where(y_list[0] == -1)[0]]
+            sample_no_list.append(ax.x_bottom.size)
+            ax.x_top = x_list[0][np.where(y_list[0] == 1)[0]]
+            sample_no_list.append(ax.x_top.size)
             sample_no_colors = [clr[d_color], clr[d_color]]
         else:
             sample_no_list = [sum([len(x) for x in x_list])]
@@ -309,8 +311,10 @@ class Plotting:
                                     mec=clr[d_color],
                                     picker=True, pickradius=3)
 
-        ax.x_list = x_list
-        ax.y_list = y_list
+        if chan_id != 'GPS Lk/Unlk':
+            ax.x_list = x_list
+            ax.y_list = y_list
+
         ax.chan_db_info = chan_db_info
         return ax
 
diff --git a/sohstationviewer/view/plotting/plotting_widget/plotting_axes.py b/sohstationviewer/view/plotting/plotting_widget/plotting_axes.py
index cbe97d14472c1054915a2e7f9f9f32b1ab4a0d11..a5ced409fbc624585f4014e7a9c6fac4910270e2 100644
--- a/sohstationviewer/view/plotting/plotting_widget/plotting_axes.py
+++ b/sohstationviewer/view/plotting/plotting_widget/plotting_axes.py
@@ -240,9 +240,8 @@ class PlottingAxes:
             # bottom_total_point_lbl, top_total_point_lbl are label to diplay
             # total number of data points which are splitted into top
             # and bottom. The ax needs to include attributes x_bottom and x_top
-            # The plotTypes that use these labels are upDownDots (and linesDot
-            # with channel='GPS Lk/Unlk' which will have another MR to add
-            # x_bottom and x_top for this)
+            # The plotTypes that use these labels are upDownDots and linesDot
+            # with channel='GPS Lk/Unlk'
             ax.bottom_total_point_lbl = ax.text(
                 1.005, sample_no_pos[0],
                 sample_no_list[0],
@@ -290,14 +289,22 @@ class PlottingAxes:
             )
             self.set_axes_ylim(ax, min_y, max_y, chan_db_info)
 
-    def set_axes_ylim(self, ax, org_min_y, org_max_y, chan_db_info):
+    def set_axes_ylim(self, ax: Axes, org_min_y: float, org_max_y: float,
+                      chan_db_info: dict):
         """
         Limit y range in min_y, max_y.
         Set y tick labels at min_y, max_y
-        :param ax: matplotlib.axes.Axes - axes of a channel
-        :param min_y: float - minimum of y values
-        :param max_y: float - maximum of y values
+        :param ax: axes of a channel
+        :param min_y: minimum of y values
+        :param max_y: maximum of y values
+        :param chan_db_info: info of channel from database
         """
+        if chan_db_info['channel'] == 'GPS Lk/Unlk':
+            # to avoid case that the channel doesn't have Lk or Unlk
+            # preset min, max value so that GPS Clock Power is always in the
+            # middle
+            org_min_y = -1
+            org_max_y = 1
         min_y = round(org_min_y, 7)
         max_y = round(org_max_y, 7)
         if chan_db_info['fixPoint'] == 0 and org_max_y > org_min_y:
diff --git a/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py b/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py
index cfcfb8a0c63b1837becc4adebd15c423d6625eda..970ba1903f2ba734848ea36cd29d45c6b523006c 100755
--- a/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py
+++ b/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py
@@ -590,7 +590,7 @@ class PlottingWidget(QtWidgets.QScrollArea):
                         # again or the plot would be collapsed to one line
                         if total_points > 1:
                             self.plotting_axes.set_axes_ylim(
-                                ax, new_min_y, new_max_y)
+                                ax, new_min_y, new_max_y, ax.chan_db_info)
                     ax.center_total_point_lbl.set_text(total_points)
 
     def draw(self):
diff --git a/sohstationviewer/view/plotting/state_of_health_widget.py b/sohstationviewer/view/plotting/state_of_health_widget.py
index bc219840a012ad21555f4fe35dcdffc1e2563d98..35c32da4d5f4fc0007f88e48d14caca7017e87f7 100644
--- a/sohstationviewer/view/plotting/state_of_health_widget.py
+++ b/sohstationviewer/view/plotting/state_of_health_widget.py
@@ -64,10 +64,44 @@ class SOHWidget(MultiThreadedPlottingWidget):
         plot_type = chan_db_info['plotType']
 
         linked_ax = None
-        if chan_db_info['linkedChan'] not in [None, 'None', '']:
-            linked_ax = self.plotting_data1[chan_db_info['linkedChan']]['ax']
+        try:
+            if chan_db_info['linkedChan'] not in [None, 'None', '']:
+                linked_ax = self.plotting_data1[chan_db_info[
+                    'linkedChan']]['ax']
+        except KeyError:
+            # linkedChan not point to an actual channel
+            # which is when the channel in linkedChan doesn't have data
+            # or the channel with likedChan is plotted first
+            # (the later is prevented by
+            # move_soh_channels_with_link_to_the_end())
+            pass
         ax = getattr(self.plotting, plot_functions[plot_type][1])(
             c_data, chan_db_info, chan_id, None, linked_ax)
         c_data['ax'] = ax
-        ax.chan = chan_id
-        self.axes.append(ax)
+        if linked_ax is None:
+            # to prevent same ax is appended to self.axes twice when there is
+            # linkedChan for the channel
+            ax.chan = chan_id
+            self.axes.append(ax)
+
+    def move_soh_channels_with_link_to_the_end(self, chan_order):
+        """
+        In order to plot a channel (channel A) that is linked with another
+        channel (channel B), we need to plot B before we plot A. Because the
+        order of the channel in the data is not predetermined, we need to
+        manually move A to the end of chan_order. This is, of course,
+        assuming that channel link is at most one level deep.
+        """
+        channels_to_move = []
+
+        for channel, chan_data in self.plotting_data1.items():
+            try:
+                linked_channel = chan_data['chan_db_info']['linkedChan']
+                if linked_channel not in ['', 'None', None]:
+                    chan_order.remove(channel)
+                    channels_to_move.append(channel)
+            except KeyError:
+                continue
+
+        for channel in channels_to_move:
+            chan_order.append(channel)