diff --git a/sohstationviewer/view/plotting/plotting_widget/plotting.py b/sohstationviewer/view/plotting/plotting_widget/plotting.py
index b9321d8d92b1d548464d6572b7b9b1754c78957c..c8ed65de9840b15c735ff12c3ec25fe21aa846e6 100644
--- a/sohstationviewer/view/plotting/plotting_widget/plotting.py
+++ b/sohstationviewer/view/plotting/plotting_widget/plotting.py
@@ -109,15 +109,88 @@ class Plotting:
         total_samples = len(x)
 
         if len(colors) != 1:
-            sample_no_colors = [clr['W']]
+            sample_no_colors = [None, clr['W'], None]
         else:
-            sample_no_colors = [clr[colors[0]]]
+            sample_no_colors = [None, clr[colors[0]], None]
 
         self.plotting_axes.set_axes_info(
-            ax, [total_samples], sample_no_colors=sample_no_colors,
+            ax, sample_no_list=[None, total_samples, None],
+            sample_no_colors=sample_no_colors,
+            sample_no_pos=[None, 0.5, None],
+            chan_db_info=chan_db_info, linked_ax=linked_ax)
+
+        ax.x_center = c_data['times'][0]
+        ax.chan_db_info = chan_db_info
+        return ax
+
+    def plot_tri_colors(self, c_data, chan_db_info, chan_id,
+                        ax, linked_ax):
+        """
+        Plot 3 different values in 3 lines with 3 different colors according
+        to valueColors:
+            Ex: -1:M|0:R|1:Y  means
+                value = -1  => plot on line y=-1 with M color
+                value = 0   => plot on line y=0 with R color
+                value = 1 => plot on line y=1 with Y color
+        Color codes are defined in colorSettings and limitted in 'valColRE'
+            in dbSettings.py
+
+        :param c_data: data of the channel which includes down-sampled
+            data in keys 'times' and 'data'. Refer to DataTypeModel.__init__.
+            soh_data[key][chan_id]
+        :param chan_db_info: dict - info of channel from DB
+        :param chan_id: name of channel
+        :param ax: axes to draw plot of channel
+        :param linked_ax:  axes of another channel
+            linked to this channel => both channels' will be plotted on the
+            same axes
+        :return ax: axes of the channel
+        """
+        if linked_ax is not None:
+            ax = linked_ax
+        if ax is None:
+            plot_h = self.plotting_axes.get_height(chan_db_info['height'])
+            ax = self.plotting_axes.create_axes(
+                self.parent.plotting_bot, plot_h,
+                has_min_max_lines=False)
+
+        value_colors = chan_db_info['valueColors'].split('|')
+
+        sample_no_colors = []
+        total_sample_list = []
+        for vc in value_colors:
+            v, c = vc.split(':')
+            sample_no_colors.append(clr[c])
+            val = get_val(v)
+            indexes = np.where(c_data['data'][0] == val)[0]
+            times = c_data['times'][0][indexes]
+
+            # base line
+            ax.plot([self.parent.min_x, self.parent.max_x],
+                    [val, val],
+                    color=clr['r'],
+                    linewidth=0.5,
+                    zorder=constants.Z_ORDER['CENTER_LINE']
+                    )
+            ax.plot(times, len(times) * [val], linestyle="",
+                    marker='s', markersize=2,
+                    zorder=constants.Z_ORDER['DOT'],
+                    color=clr[c], picker=True, pickradius=3)
+
+            total_sample_list.append(len(times))
+            if val == -1:
+                ax.x_bottom = times
+            elif val == 0:
+                ax.x_center = times
+            else:
+                ax.x_top = times
+
+        self.plotting_axes.set_axes_info(
+            ax, sample_no_list=total_sample_list,
+            sample_no_colors=sample_no_colors,
+            sample_no_pos=[0.05, 0.5, 0.95],
             chan_db_info=chan_db_info, linked_ax=linked_ax)
 
-        ax.x_list = c_data['times']
         ax.chan_db_info = chan_db_info
         return ax
 
@@ -174,9 +247,10 @@ class Plotting:
 
         ax.set_ylim(-2, 2)
         self.plotting_axes.set_axes_info(
-            ax, [len(points_list[0]), len(points_list[1])],
-            sample_no_colors=[clr[colors[0]], clr[colors[1]]],
-            sample_no_pos=[0.25, 0.75],
+            ax,
+            sample_no_list=[len(points_list[0]), None, len(points_list[1])],
+            sample_no_colors=[clr[colors[0]], None, clr[colors[1]]],
+            sample_no_pos=[0.25, None, 0.75],
             chan_db_info=chan_db_info, linked_ax=linked_ax)
 
         # x_bottom, x_top are the times of data points to be displayed at
@@ -215,7 +289,9 @@ class Plotting:
         x_list = c_data['times']
         total_x = sum([len(x) for x in x_list])
         self.plotting_axes.set_axes_info(
-            ax, [total_x], sample_no_colors=[clr[color]],
+            ax, sample_no_list=[None, total_x, None],
+            sample_no_colors=[None, clr[color], None],
+            sample_no_pos=[None, 0.5, None],
             chan_db_info=chan_db_info, linked_ax=linked_ax)
 
         for x in x_list:
@@ -223,7 +299,7 @@ class Plotting:
                     linestyle='', zorder=constants.Z_ORDER['LINE'],
                     color=clr[color], picker=True,
                     pickradius=3)
-        ax.x_list = x_list
+        ax.x_center = x_list[0]
         ax.chan_db_info = chan_db_info
         return ax
 
@@ -282,21 +358,28 @@ class Plotting:
             sample_no_list = []
             ax.x_bottom = x_list[0][np.where(y_list[0] == -1)[0]]
             sample_no_list.append(ax.x_bottom.size)
+            sample_no_list.append(None)
             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]]
+            sample_no_colors = [clr[d_color], None, clr[d_color]]
+            sample_no_pos = [0.05, None, 0.95]
         else:
-            sample_no_list = [sum([len(x) for x in x_list])]
-            sample_no_colors = [clr[d_color]]
+            sample_no_list = [None, sum([len(x) for x in x_list]), None]
+            sample_no_colors = [None, clr[d_color], None]
+            sample_no_pos = [None, 0.5, None]
         self.plotting_axes.set_axes_info(
-            ax, sample_no_list, sample_no_colors=sample_no_colors,
+            ax, sample_no_list=sample_no_list,
+            sample_no_colors=sample_no_colors,
+            sample_no_pos=sample_no_pos,
             chan_db_info=chan_db_info,
             info=info, y_list=y_list, linked_ax=linked_ax)
 
         for x, y in zip(x_list, y_list):
-            if not has_dot and sample_no_list[0] > 1:
-                # set marker to be able to click point for info
-                # but marker's size is small to not show dot.
+            if not has_dot and sample_no_list[1] > 1:
+                # When only line, set marker size small to not show dot.
+                # But set pick radius bigger to be easier to click on.
+                # This only apply when sample_no_list[1] > 1 because
+                # when it is 1, need to show dot or nothing will be plotted.
                 ax.myPlot = ax.plot(x, y, marker='o', markersize=0.01,
                                     linestyle='-', linewidth=0.7,
                                     zorder=constants.Z_ORDER['LINE'],
@@ -312,8 +395,8 @@ class Plotting:
                                     picker=True, pickradius=3)
 
         if chan_id != 'GPS Lk/Unlk':
-            ax.x_list = x_list
-            ax.y_list = y_list
+            ax.x_center = x_list[0]
+            ax.y_list = y_list[0]
 
         ax.chan_db_info = chan_db_info
         return ax
@@ -375,7 +458,10 @@ class Plotting:
         x_list, y_list = c_data['times'], c_data['data']
         total_x = sum([len(x) for x in x_list])
         self.plotting_axes.set_axes_info(
-            ax, [total_x], chan_db_info=chan_db_info, y_list=y_list)
+            ax, sample_no_list=[None, total_x, None],
+            sample_no_colors=[None, clr['W'], None],
+            sample_no_pos=[None, 0.5, None],
+            chan_db_info=chan_db_info, y_list=y_list)
         for x, y in zip(x_list, y_list):
             ax.myPlot = ax.plot(x, y,
                                 linestyle='-', linewidth=0.7,
@@ -399,7 +485,7 @@ class Plotting:
                     count += 1
             ax.scatter(x, y, marker='s', c=colors, s=sizes,
                        zorder=constants.Z_ORDER['DOT'])
-        ax.x_list = x_list
-        ax.y_list = y_list
+        ax.x_center = x_list[0]
+        ax.y_center = y_list[0]
         ax.chan_db_info = chan_db_info
         return ax
diff --git a/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py b/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py
index fc266795d2105547dba6f150a23242e4085b60f9..3bd5ab3805a4d620fab3ffe4d7a85a0f69c40443 100755
--- a/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py
+++ b/sohstationviewer/view/plotting/plotting_widget/plotting_widget.py
@@ -583,10 +583,10 @@ class PlottingWidget(QtWidgets.QScrollArea):
                         (ax.x_top <= self.max_x))[0]
                     ax.top_total_point_lbl.set_text(
                         new_x_top_indexes.size)
-                if hasattr(ax, 'x_list'):
-                    if not hasattr(ax, 'y_list'):
+                if hasattr(ax, 'x_center'):
+                    if not hasattr(ax, 'y_center'):
                         # plot_time_dots and plot_multi_color_dots
-                        x = ax.x_list[0]
+                        x = ax.x_center
                         new_x_indexes = np.where(
                             (x >= self.min_x) & (x <= self.max_x))[0]
                         ax.center_total_point_lbl.set_text(new_x_indexes.size)
@@ -594,17 +594,17 @@ class PlottingWidget(QtWidgets.QScrollArea):
                     total_points = 0
                     tr_min_ys = []
                     tr_max_ys = []
-                    for x, y in zip(ax.x_list, ax.y_list):
-                        if len(x) == 0:
-                            continue
-                        if self.min_x > x[-1] or self.max_x < x[0]:
-                            continue
-                        ret = get_total_miny_maxy(x, y, self.min_x, self.max_x)
-                        total_tr_points, tr_min_y, tr_max_y = ret
-                        total_points += total_tr_points
-                        if tr_min_y is not None:
-                            tr_min_ys.append(tr_min_y)
-                            tr_max_ys.append(tr_max_y)
+                    x, y = ax.x_list, ax.y_list
+                    if len(x) == 0:
+                        continue
+                    if self.min_x > x[-1] or self.max_x < x[0]:
+                        continue
+                    ret = get_total_miny_maxy(x, y, self.min_x, self.max_x)
+                    total_tr_points, tr_min_y, tr_max_y = ret
+                    total_points += total_tr_points
+                    if tr_min_y is not None:
+                        tr_min_ys.append(tr_min_y)
+                        tr_max_ys.append(tr_max_y)
                     if tr_min_ys != []:
                         new_min_y = min(tr_min_ys)
                         new_max_y = max(tr_max_ys)