Repository: mne-tools/mne-python

Issue:
ENH/VIZ: display .nave by default in plot_evoked
I was thinking repeatedly for months that having the .nave output by default in the title or so of plot_evoked would be so useful. What do you think?

cc @jona-sassenhagen @mmagnuski 



Discussion:
A parenthetical after the condition name would be nice
Probably better than what we have right now :)
> A parenthetical after the condition name would be nice

yes

> Probably better than what we have right now :)

and yes.

Great, so it seems some people like it. Let's do it! Marking as easy.
@massich maybe something you could like to look into, relaxing from pytests.
I like that too :)
> I like that too :)

great!
Hi,
Can I get some reference to the problem and what sort of script is required to be written.
And this is related to which objective.

Or if I can get some doc to look into
Hi @thesujitroy have a look at some of the basic tutorials that compute evoked responses and call ```evoked.plot()```. You will notices that no information on the number of averages (nave) is present. The idea is to find a way to show the evoked.nave attribute when plotting. mne.viz.plot_evoked needs to be updated for that. I hope this helps.
Alright. Thank you

I  am taking this issue.
Great! Don't hesitate moving in small steps. It is bettet to start
somewhere and communicate early. Perfection comes in iterations.

On Fri, Mar 2, 2018 at 11:01 AM thesujitroy <notifications@github.com>
wrote:

> I am taking this issue.
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/mne-tools/mne-python/issues/4484#issuecomment-369877887>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AB0fig7oCncjbSvAY4wFb5n7zyGuN7t1ks5taRhmgaJpZM4O2apD>
> .
>

Hi,
I was going through the code and it seems that nave is declared to be 1.
However, in plot_evoked the attribute needs to be added. But I cant understand the attributes we are trying to show is evoked.nave, this needs to show in plot in what form.
Can the Number of averages be more than 1, and are trying to put it in butterfly plot? 
we can fetch information of "nave" from evoked.nave
i.e info = evoked.nave ?
> But I cant understand the attributes we are trying to show is evoked.nave, this needs to show in plot in what form.

See comment [from above](https://github.com/mne-tools/mne-python/issues/4484#issuecomment-322205698)

> Can the Number of averages be more than 1, and are trying to put it in butterfly plot?

It's the number of trials used in the average for the evoked, i.e., evoked.nave

@thesujitroy any progress?

Resolving patch:
diff --git a/mne/viz/evoked.py b/mne/viz/evoked.py
--- a/mne/viz/evoked.py
+++ b/mne/viz/evoked.py
@@ -273,16 +273,18 @@ def _plot_evoked(evoked, picks, exclude, unit, show, ylim, proj, xlim, hline,
         _plot_lines(evoked.data, info, picks, fig, axes, spatial_colors, unit,
                     units, scalings, hline, gfp, types, zorder, xlim, ylim,
                     times, bad_ch_idx, titles, ch_types_used, selectable,
-                    False, line_alpha=1.)
+                    False, line_alpha=1., nave=evoked.nave)
         plt.setp(axes, xlabel='Time (ms)')
 
     elif plot_type == 'image':
-        for ax, this_type in zip(axes, ch_types_used):
+        for ai, (ax, this_type) in enumerate(zip(axes, ch_types_used)):
+            use_nave = evoked.nave if ai == 0 else None
             this_picks = list(picks[types == this_type])
             _plot_image(evoked.data, ax, this_type, this_picks, cmap, unit,
                         units, scalings, evoked.times, xlim, ylim, titles,
                         colorbar=colorbar, mask=mask, mask_style=mask_style,
-                        mask_cmap=mask_cmap, mask_alpha=mask_alpha)
+                        mask_cmap=mask_cmap, mask_alpha=mask_alpha,
+                        nave=use_nave)
     if proj == 'interactive':
         _check_delayed_ssp(evoked)
         params = dict(evoked=evoked, fig=fig, projs=info['projs'], axes=axes,
@@ -303,9 +305,9 @@ def _plot_evoked(evoked, picks, exclude, unit, show, ylim, proj, xlim, hline,
 def _plot_lines(data, info, picks, fig, axes, spatial_colors, unit, units,
                 scalings, hline, gfp, types, zorder, xlim, ylim, times,
                 bad_ch_idx, titles, ch_types_used, selectable, psd,
-                line_alpha):
+                line_alpha, nave):
     """Plot data as butterfly plot."""
-    from matplotlib import patheffects
+    from matplotlib import patheffects, pyplot as plt
     from matplotlib.widgets import SpanSelector
     texts = list()
     idxs = list()
@@ -336,7 +338,7 @@ def _plot_lines(data, info, picks, fig, axes, spatial_colors, unit, units,
         fig.canvas.mpl_connect('button_press_event',
                                partial(_butterfly_on_button_press,
                                        params=params))
-    for ax, this_type in zip(axes, ch_types_used):
+    for ai, (ax, this_type) in enumerate(zip(axes, ch_types_used)):
         line_list = list()  # 'line_list' contains the lines for this axes
         if unit is False:
             this_scaling = 1.0
@@ -433,16 +435,16 @@ def _plot_lines(data, info, picks, fig, axes, spatial_colors, unit, units,
                 ax.set_xlim(xlim)
             if ylim is not None and this_type in ylim:
                 ax.set_ylim(ylim[this_type])
-            ax.set_title(titles[this_type] + ' (%d channel%s)' % (len(D),
-                                                                  _pl(D)))
-
+            ax.set(title=r'%s (%d channel%s)'
+                   % (titles[this_type], len(D), _pl(len(D))))
+            if ai == 0:
+                _add_nave(ax, nave)
             if hline is not None:
                 for h in hline:
                     c = ('grey' if spatial_colors is True else 'r')
                     ax.axhline(h, linestyle='--', linewidth=2, color=c)
         lines.append(line_list)
     if selectable:
-        import matplotlib.pyplot as plt
         for ax in np.array(axes)[selectables]:
             if len(ax.lines) == 1:
                 continue
@@ -461,6 +463,15 @@ def _plot_lines(data, info, picks, fig, axes, spatial_colors, unit, units,
                 useblit=blit, rectprops=dict(alpha=0.5, facecolor='red'))
 
 
+def _add_nave(ax, nave):
+    """Add nave to axes."""
+    if nave is not None:
+        ax.annotate(
+            r'N$_{\mathrm{ave}}$=%d' % nave, ha='left', va='bottom',
+            xy=(0, 1), xycoords='axes fraction',
+            xytext=(0, 5), textcoords='offset pixels')
+
+
 def _handle_spatial_colors(colors, info, idx, ch_type, psd, ax):
     """Set up spatial colors."""
     used_nm = np.array(_clean_names(info['ch_names']))[idx]
@@ -476,7 +487,7 @@ def _handle_spatial_colors(colors, info, idx, ch_type, psd, ax):
 
 def _plot_image(data, ax, this_type, picks, cmap, unit, units, scalings, times,
                 xlim, ylim, titles, colorbar=True, mask=None, mask_cmap=None,
-                mask_style=None, mask_alpha=.25):
+                mask_style=None, mask_alpha=.25, nave=None):
     """Plot images."""
     import matplotlib.pyplot as plt
 
@@ -565,8 +576,9 @@ def _plot_image(data, ax, this_type, picks, cmap, unit, units, scalings, times,
             t_end = ", " + str(percent) + "% of points masked)"
     else:
         t_end = ")"
-    ax.set_title(
-        titles[this_type] + ' (%d channel%s' % (len(data), _pl(data)) + t_end)
+    ax.set(title='%s (%d channel%s%s'
+           % (titles[this_type], len(data), _pl(len(data)), t_end))
+    _add_nave(ax, nave)
 
 
 @verbose
@@ -1133,8 +1145,8 @@ def whitened_gfp(x, rank=None):
                     lw=0.5)
             for hline in [-1.96, 1.96]:
                 ax.axhline(hline, color='red', linestyle='--', lw=2)
-            ax.set(title='{0} ({1} channels)'.format(titles_[ch_type],
-                                                     len(picks)))
+            ax.set(title='%s (%d channel%s)'
+                   % (titles_[ch_type], len(picks), _pl(len(picks))))
 
     # Now plot the GFP for all covs if indicated.
     for evoked_white, noise_cov, rank_, color in iter_gfp:
diff --git a/mne/viz/raw.py b/mne/viz/raw.py
--- a/mne/viz/raw.py
+++ b/mne/viz/raw.py
@@ -838,7 +838,7 @@ def plot_raw_psd(raw, tmin=0., tmax=np.inf, fmin=0, fmax=np.inf, proj=False,
                     types=types, zorder='std', xlim=(freqs[0], freqs[-1]),
                     ylim=None, times=freqs, bad_ch_idx=[], titles=titles,
                     ch_types_used=ch_types_used, selectable=True, psd=True,
-                    line_alpha=line_alpha)
+                    line_alpha=line_alpha, nave=None)
     for ax in ax_list:
         ax.grid(True, linestyle=':')
         if xscale == 'log':
diff --git a/tutorials/plot_visualize_evoked.py b/tutorials/plot_visualize_evoked.py
--- a/tutorials/plot_visualize_evoked.py
+++ b/tutorials/plot_visualize_evoked.py
@@ -5,7 +5,7 @@
 Visualize Evoked data
 =====================
 
-In this tutorial we focus on plotting functions of :class:`mne.Evoked`.
+In this tutorial we focus on the plotting functions of :class:`mne.Evoked`.
 """
 import os.path as op
 import numpy as np


Test patch: