diff --git a/sohstationviewer/view/main_window.py b/sohstationviewer/view/main_window.py
index 4775539e1f3f437a98e81ad232b7486b28f64218..666c94cf570f00402414fbeebac09127ce5ca06d 100755
--- a/sohstationviewer/view/main_window.py
+++ b/sohstationviewer/view/main_window.py
@@ -739,7 +739,8 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
 
         try:
             self.plotting_widget.plot_channels(
-                d_obj, sel_key, self.start_tm, self.end_tm, time_tick_total)
+                d_obj, sel_key, self.start_tm, self.end_tm, time_tick_total,
+                self.req_soh_chans)
         except Exception:
             fmt = traceback.format_exc()
             msg = f"Can't plot SOH data due to error: {str(fmt)}"
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 229544d77488a53b07c49a8a6b7254d969a92e22..7e52995e0291415225e0c5661b4deac3967391f4 100644
--- a/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
+++ b/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
@@ -11,6 +11,8 @@ from sohstationviewer.view.plotting.plotting_widget.plotting_processor import (
 from sohstationviewer.view.plotting.plotting_widget.plotting_widget import (
     PlottingWidget)
 from sohstationviewer.view.util.enums import LogType
+from sohstationviewer.view.util.functions import (
+    replace_actual_quest_chans, remove_not_found_chans)
 
 from sohstationviewer.controller.util import display_tracking_info
 from sohstationviewer.controller.plotting_data import get_title
@@ -106,21 +108,34 @@ class MultiThreadedPlottingWidget(PlottingWidget):
 
     def create_plotting_channel_processors(
             self, plotting_data: Dict,
-            get_plot_info: Optional[Callable[[str, Dict, str], Dict]]) -> None:
+            get_plot_info: Optional[Callable[[str, Dict, str], Dict]],
+            pref_order: List[str] = []) -> None:
         """
-        Create a data processor for each channel data.
+        Create a data processor for each channel data in the order of
+            pref_order. If pref_order isn't given, process in order of
+            plotting_data.
 
         :param plotting_data: dict of data by chan_id
         :param get_plot_info: function to get plotting info from database
+        :param pref_order: order of channels to be plotted
         """
-        for chan_id in plotting_data:
+        chan_order = pref_order if pref_order else list(plotting_data.keys())
+        chan_order = replace_actual_quest_chans(
+            chan_order, plotting_data.keys())
+        chan_order = remove_not_found_chans(
+            chan_order, plotting_data.keys(), self.processing_log)
+
+        not_plot_chans = []
+        for chan_id in chan_order:
             if get_plot_info is not None:
                 chan_db_info = get_plot_info(chan_id,
                                              plotting_data[chan_id],
                                              self.parent.data_type,
                                              self.c_mode)
-                if chan_db_info['height'] == 0:
+                if (chan_db_info['height'] == 0 or
+                        chan_db_info['plotType'] == ''):
                     # not draw
+                    not_plot_chans.append(chan_id)
                     continue
                 if 'DEFAULT' in chan_db_info['channel']:
                     msg = (f"Channel {chan_id}'s "
@@ -130,19 +145,16 @@ class MultiThreadedPlottingWidget(PlottingWidget):
                     #  instruction here
                     self.processing_log.append((msg, LogType.WARNING))
 
-                if chan_db_info['plotType'] == '':
-                    continue
-
-                # These channels contain GPS data which are only shown in
-                # the GPS dialog.
-                if chan_id in {'GLO', 'VLO', 'VLA', 'GLA', 'VEL', 'VNS', 'GNS',
-                               'GEL'}:
-                    continue
                 plotting_data[chan_id]['chan_db_info'] = chan_db_info
+        if not_plot_chans != []:
+            msg = (f"The database settings 'plotType' or 'height' show not to "
+                   f"be plotted for the following channels: "
+                   f"{', '.join( not_plot_chans)}")
+            self.processing_log.append((msg, LogType.WARNING))
 
         self.move_soh_channels_with_link_to_the_end()
 
-        for chan_id in plotting_data:
+        for chan_id in chan_order:
             if 'chan_db_info' not in plotting_data[chan_id]:
                 continue
             channel_processor = PlottingChannelProcessor(
@@ -173,7 +185,8 @@ class MultiThreadedPlottingWidget(PlottingWidget):
         for channel in channels_to_move:
             self.plotting_data1[channel] = self.plotting_data1.pop(channel)
 
-    def plot_channels(self, d_obj, key, start_tm, end_tm, time_ticks_total):
+    def plot_channels(self, d_obj, key, start_tm, end_tm, time_ticks_total,
+                      pref_soh_order=[]):
         """
         Prepare to plot waveform/SOH/mass-position data by creating a data
         processor for each channel, then, run the processors.
@@ -183,6 +196,7 @@ class MultiThreadedPlottingWidget(PlottingWidget):
         :param start_tm: requested start time to read
         :param end_tm: requested end time to read
         :param time_ticks_total: max number of tick to show on time bar
+        :param pref_order: order of channels to be plotted
         """
         if not self.is_working:
             self.reset_widget()
@@ -197,7 +211,7 @@ class MultiThreadedPlottingWidget(PlottingWidget):
                 self.finished.emit()
                 return
             self.create_plotting_channel_processors(
-                self.plotting_data1, self.get_plot_info)
+                self.plotting_data1, self.get_plot_info, pref_soh_order)
             self.create_plotting_channel_processors(
                 self.plotting_data2, get_chan_plot_info)
             self.process_channel()
diff --git a/sohstationviewer/view/util/functions.py b/sohstationviewer/view/util/functions.py
index 2927cae8c88a35dbe38423b4448c5c615c469da9..60e2883b3d3f3da756a80d614ad4b943d0563c9a 100644
--- a/sohstationviewer/view/util/functions.py
+++ b/sohstationviewer/view/util/functions.py
@@ -325,5 +325,45 @@ def get_index_from_time(chan_data: List[np.ndarray], tm: float, val: float) \
     return list_idx, section_idx
 
 
+def remove_not_found_chans(
+        chan_order: List[str], actual_chans: List[str],
+        processing_log: List[Tuple[str, LogType]]) -> List[str]:
+    """
+    Remove channels that are not found in actual_chans from chan_order.
+
+    :param chan_order: The list of channel that have channels end with '?'
+    :param actual_chans: The actual channel list
+    :param processing_log: The log list to keep track with not found channels
+    :return: chan_order from which not found channels have been removed.
+    """
+    not_found_chans = [c for c in chan_order if c not in actual_chans]
+    if not_found_chans != []:
+        msg = (f"No data found for the following channels: "
+               f"{', '.join(not_found_chans)}")
+        processing_log.append((msg, LogType.WARNING))
+    return [c for c in chan_order if c not in not_found_chans]
+
+
+def replace_actual_quest_chans(
+        chan_order: List[str], actual_chans: List[str]) -> List[str]:
+    """
+    Remove channels end with '?' from chan_order and replace with corresponding
+        channels found in actual channels.
+
+    :param chan_order: The list of channel that have channels end with '?'
+    :param actual_chans: The actual channel list
+    :return: chan_order that have channels end with '?' replaced by actual
+        channels.
+    """
+    quest_chans = [c for c in chan_order if c.endswith('?')]
+    for qc in quest_chans:
+        actual_quest_chans = [c for c in list(actual_chans)
+                              if qc[:-1] == c[:-1]]
+        quest_idx = chan_order.index(qc)
+        chan_order.remove(qc)
+        chan_order[quest_idx:quest_idx] = sorted(actual_quest_chans)
+    return chan_order
+
+
 if __name__ == '__main__':
     create_table_of_content_file(Path('../../../documentation'))