Repository: mne-tools/mne-python

Issue:
How to define channel types on the fly
In my lab we use multiple synced signals (EEG, eye-tracking, ...), and one of them is information of spatial markers (ndigital optotrak). I create RawArrays from the spatial data with 'misc' channel types. The problem is that every time I want to plot the evoked data a __ValueError: Non-data channel picked.__ is raised. My temporary (lazy) solution is to change the channels types to a valid one (as those defined in _DATA_CH_TYPES_SPLIT), but it is far from a good solution. So it would be nice if I could define a channel type (with its units to plot, etc) when using other ___non-standard___ data types (e.g. eye-tracking/mouse-tracking channels in pixels or mm, spatial markers in mm, among others) while profiting of this great software.



Discussion:
you mean evoked.plot crashes when you try to plot a misc channel?

I don't know if it is a crash or expected behavior. For example, in [plot_compare_evokeds line 1475](https://github.com/mne-tools/mne-python/blob/master/mne/viz/evoked.py#L1475) If any channel doesn't belong to _DATA_CH_TYPES_SPLIT (defined in io.pick [here](https://github.com/mne-tools/mne-python/blob/master/mne/io/pick.py#L715)) the value error is raised.

That is not the case with plot_evoked as misc channels are defined as valid [here](https://github.com/mne-tools/mne-python/blob/master/mne/viz/evoked.py#L202). So my apologies for not specifying the function with the problem.
if evoked.plot supports misc then it should also be the case for the
plot_compare_evokeds function

can you open a PR to fix it yourself?


Resolving patch:
diff --git a/mne/io/pick.py b/mne/io/pick.py
--- a/mne/io/pick.py
+++ b/mne/io/pick.py
@@ -714,6 +714,11 @@ def _check_excludes_includes(chs, info=None, allow_bads=False):
 _PICK_TYPES_KEYS = tuple(list(_PICK_TYPES_DATA_DICT.keys()) + ['ref_meg'])
 _DATA_CH_TYPES_SPLIT = ['mag', 'grad', 'eeg', 'seeg', 'ecog', 'hbo', 'hbr']
 
+# Valid data types, ordered for consistency, used in viz/evoked.
+_VALID_CHANNEL_TYPES = ['eeg', 'grad', 'mag', 'seeg', 'eog', 'ecg', 'emg',
+                        'dipole', 'gof', 'bio', 'ecog', 'hbo', 'hbr',
+                        'misc']
+
 
 def _pick_data_channels(info, exclude='bads', with_ref_meg=True):
     """Pick only data channels."""
diff --git a/mne/viz/evoked.py b/mne/viz/evoked.py
--- a/mne/viz/evoked.py
+++ b/mne/viz/evoked.py
@@ -16,7 +16,7 @@
 import numpy as np
 
 from ..io.pick import (channel_type, pick_types, _picks_by_type,
-                       _pick_data_channels, _DATA_CH_TYPES_SPLIT)
+                       _pick_data_channels, _VALID_CHANNEL_TYPES)
 from ..externals.six import string_types
 from ..defaults import _handle_default
 from .utils import (_draw_proj_checkbox, tight_layout, _check_delayed_ssp,
@@ -196,10 +196,6 @@ def _plot_evoked(evoked, picks, exclude, unit, show, ylim, proj, xlim, hline,
     scalings = _handle_default('scalings', scalings)
     titles = _handle_default('titles', titles)
     units = _handle_default('units', units)
-    # Valid data types ordered for consistency
-    valid_channel_types = ['eeg', 'grad', 'mag', 'seeg', 'eog', 'ecg', 'emg',
-                           'dipole', 'gof', 'bio', 'ecog', 'hbo', 'hbr',
-                           'misc']
 
     if picks is None:
         picks = list(range(info['nchan']))
@@ -221,7 +217,7 @@ def _plot_evoked(evoked, picks, exclude, unit, show, ylim, proj, xlim, hline,
 
     types = np.array([channel_type(info, idx) for idx in picks])
     ch_types_used = list()
-    for this_type in valid_channel_types:
+    for this_type in _VALID_CHANNEL_TYPES:
         if this_type in types:
             ch_types_used.append(this_type)
 
@@ -1458,6 +1454,10 @@ def plot_compare_evokeds(evokeds, picks=list(), gfp=False, colors=None,
         gfp = True
         picks = _pick_data_channels(example.info)
 
+        if len(picks) == 0:
+            raise ValueError("No valid channels were found to plot the GFP. " +
+                             "Use 'picks' instead to select them manually.")
+
     # deal with picks: infer indices and names
     if gfp is True:
         ch_names = ['Global Field Power']
@@ -1472,7 +1472,7 @@ def plot_compare_evokeds(evokeds, picks=list(), gfp=False, colors=None,
     ch_types = list(set(channel_type(example.info, pick_)
                     for pick_ in picks))
     # XXX: could possibly be refactored; plot_joint is doing a similar thing
-    if any([type_ not in _DATA_CH_TYPES_SPLIT for type_ in ch_types]):
+    if any([type_ not in _VALID_CHANNEL_TYPES for type_ in ch_types]):
         raise ValueError("Non-data channel picked.")
     if len(ch_types) > 1:
         warn("Multiple channel types selected, returning one figure per type.")


Test patch: