def plot_erp(self, inst): tps = mne_types() from mne.viz import plot_compare_evokeds picks = [inst.ch_names.index(ch) for ch in self._chan_names] if isinstance(inst, tps['epochs']): erps = {c: inst[c].average() for c in inst.event_id.keys()} fig = plot_compare_evokeds(erps, picks=picks) else: fig = plot_compare_evokeds(inst, picks=picks) fig.set_facecolor('white') return fig
times=[.13, .23]) fig.axes[0].set_ylabel('T-value') ############################################################################### # correct p-values for multiple testing and create a mask for non-significant # time point dor each channel. reject_H0, fdr_pvals = fdr_correction(p_vals[predictor], alpha=0.01) # plot t-values, masking non-significant time points. fig = t_vals[predictor].plot_image( time_unit='s', mask=reject_H0, unit=False, # keep values scale scalings=dict(eeg=1)) fig.axes[1].set_title('T-value') ############################################################################### # plot surprise-values as "erp" # only show electrode `B8` pick = epochs.info['ch_names'].index('B8') fig, ax = plt.subplots(figsize=(7, 4)) plot_compare_evokeds(s_vals[predictor], picks=pick, legend='lower left', axes=ax, show_sensors='upper left') plt.rcParams.update({'mathtext.default': 'regular'}) ax.set_ylabel('$S_{value}$ (-$log_2$($P_{value}$)') ax.yaxis.set_label_coords(-0.1, 0.5) plt.plot()
epochs = mne.read_epochs(path) print(epochs.metadata.head()) ############################################################################## # Psycholinguistically relevant word characteristics are continuous. I.e., # concreteness or imaginability is a graded property. In the metadata, # we have concreteness ratings on a 5-point scale. We can show the dependence # of the EEG on concreteness by dividing the data into bins and plotting the # mean activity per bin, color coded. name = "Concreteness" df = epochs.metadata df[name] = pd.cut(df[name], 11, labels=False) / 10 colors = {str(val): val for val in df[name].unique()} epochs.metadata = df.assign(Intercept=1) # Add an intercept for later evokeds = {val: epochs[name + " == " + val].average() for val in colors} plot_compare_evokeds(evokeds, colors=colors, split_legend=True, cmap=(name + " Percentile", "viridis")) ############################################################################## # We observe that there appears to be a monotonic dependence of EEG on # concreteness. We can also conduct a continuous analysis: single-trial level # regression with concreteness as a continuous (although here, binned) # feature. We can plot the resulting regression coefficient just like an # Event-related Potential. names = ["Intercept", name] res = linear_regression(epochs, epochs.metadata[names], names=names) for cond in names: res[cond].beta.plot_joint(title=cond, ts_args=dict(time_unit='s'), topomap_args=dict(time_unit='s')) ############################################################################## # Because the `linear_regression` function also estimates p values, we can --
# plot results of linear regression # only show -250 to 500 ms ts_args = dict(xlim=(-.25, 0.5)) # predictor to plot predictor = 'phase-coherence' # electrode to plot pick = epochs.info['ch_names'].index('B8') # visualise effect of phase-coherence for sklearn estimation method. lm_betas[predictor].plot_joint(ts_args=ts_args, title='Phase-coherence (sklearn betas)', times=[.23]) # create plot for the effect of phase-coherence on electrode B8 # with 95% confidence interval fig, ax = plt.subplots(figsize=(8, 5)) plot_compare_evokeds(lm_betas[predictor], picks=pick, ylim=dict(eeg=[-11, 1]), colors=['k'], legend='lower left', axes=ax) ax.fill_between(epochs.times, ci['lower_bound'][predictor][pick] * 1e6, ci['upper_bound'][predictor][pick] * 1e6, color=['k'], alpha=0.2) plt.plot()
def PreProcess(raw, event_id, plot_psd=False, filter_data=True, filter_range=(1, 30), plot_events=False, epoch_time=(-.2, 1), baseline=(-.2, 0), rej_thresh_uV=200, rereference=False, emcp_raw=False, emcp_epochs=False, epoch_decim=1, plot_electrodes=False, plot_erp=False): sfreq = raw.info['sfreq'] #create new output freq for after epoch or wavelet decim nsfreq = sfreq / epoch_decim tmin = epoch_time[0] tmax = epoch_time[1] if filter_range[1] > nsfreq: filter_range[ 1] = nsfreq / 2.5 #lower than 2 to avoid aliasing from decim?? #pull event names in order of trigger number event_names = ['A_error', 'B_error'] i = 0 for key, value in sorted(event_id.items(), key=lambda x: (x[1], x[0])): event_names[i] = key i += 1 #Filtering if rereference: print('Rerefering to average mastoid') raw = mastoidReref(raw) if filter_data: print('Filtering Data Between ' + str(filter_range[0]) + ' and ' + str(filter_range[1]) + ' Hz.') raw.filter(filter_range[0], filter_range[1], method='iir', verbose='WARNING') if plot_psd: raw.plot_psd(fmin=filter_range[0], fmax=nsfreq / 2) #Eye Correction if emcp_raw: print('Raw Eye Movement Correction') raw = GrattonEmcpRaw(raw) #Epoching events = find_events(raw, shortest_event=1) color = {1: 'red', 2: 'black'} #artifact rejection rej_thresh = rej_thresh_uV * 1e-6 #plot event timing if plot_events: viz.plot_events(events, sfreq, raw.first_samp, color=color, event_id=event_id) #Constructevents epochs = Epochs(raw, events=events, event_id=event_id, tmin=tmin, tmax=tmax, baseline=baseline, preload=True, reject={'eeg': rej_thresh}, verbose=False, decim=epoch_decim) print('Remaining Trials: ' + str(len(epochs))) if emcp_epochs: print('Epochs Eye Movement Correct') epochs = GrattonEmcpEpochs(epochs) evoked_dict = { event_names[0]: epochs[event_names[0]].average(), event_names[1]: epochs[event_names[1]].average() } ## plot ERP at each electrode if plot_electrodes: picks = pick_types(evoked_dict[event_names[0]].info, meg=False, eeg=True, eog=False) fig_zero = evoked_dict[event_names[0]].plot(spatial_colors=True, picks=picks) fig_zero = evoked_dict[event_names[1]].plot(spatial_colors=True, picks=picks) ## plot ERP in each condition on same plot if plot_erp: #find the electrode most miximal on the head (highest in z) picks = np.argmax([ evoked_dict[event_names[0]].info['chs'][i]['loc'][2] for i in range(len(evoked_dict[event_names[0]].info['chs'])) ]) colors = {event_names[0]: "Red", event_names[1]: "Blue"} viz.plot_compare_evokeds(evoked_dict, colors=colors, picks=picks, split_legend=True) return epochs
times=np.arange(-.1, evoked.tmax, .025), show=False, average=.05, nrows=4, title=f'{cond} topomaps (.5s avg)')) # Add slider section report.add_slider_to_section( figs, section='ERP', title=f'ERP (Avg. ref.): {cond}', scale=1) plt.close() # Add Select topos to ERP # Scene vs. Objects conds = ['scene', 'object'] these_evokeds = [evokeds[evokeds_key[x]].copy().crop( tmin=-.2, tmax=.6).apply_baseline( (-.2, 0)) for x in evokeds_key.keys() if x in conds] fig1 = plot_compare_evokeds(these_evokeds, title='Scene and Object Trials', axes='topo', show=False, show_sensors=True) fig2 = plot_compare_evokeds( evokeds[evokeds_key['scene-object']].copy().crop( tmin=-.2, tmax=.6).apply_baseline((-.2, 0)), title='Scene and Object Trials - Left Hemisphere', show=False, show_sensors=True, picks=['TP7', 'P7', 'PO7'], combine='mean') fig3 = plot_compare_evokeds( evokeds[evokeds_key['scene-object']].copy().crop( tmin=-.2, tmax=.6).apply_baseline((-.2, 0)), title='Scene and Object Trials - Right Hemisphere', show=False, show_sensors=True, picks=['TP8', 'P8', 'PO8'], combine='mean') captions = [ 'Scene and Object Trials', 'Scene and Object Trials - Left Hemisphere',
f'{sub}_task-{task}_ref-avg_lpf-none_ave.json' with open(evoked_json_file, 'r') as f: evoked_json = json.load(f) evokeds_key = evoked_json['evoked_objects'] # Filter in place if requested if filter_data == 'y': print('Filtering ERPs...') for evoked in evokeds: evoked.filter(None, lcutoff, verbose=False) # Face, Scene, Object conds = ['scene', 'object', 'face'] these_evokeds = [ evokeds[evokeds_key[x]] for x in evokeds_key.keys() if x in conds ] plot_compare_evokeds(these_evokeds, axes='topo', show=True, title='Scene, Object, and Face Novel Trials') # Repeat vs. Novel Trials conds = ['novel', 'repeat'] these_evokeds = [ evokeds[evokeds_key[x]] for x in evokeds_key.keys() if x in conds ] plot_compare_evokeds(these_evokeds, axes='topo', show=True, title='Repeat vs. Novel Trials')
't7': [2.00, 0.45]} # create evokeds dict evokeds = {'Cue A': ga_a_cue.copy().crop(tmin=-0.25), 'Cue B': ga_b_cue.copy().crop(tmin=-0.25)} # use viridis colors colors = np.linspace(0, 1, len(gfp_times.values())) cmap = cm.get_cmap('viridis') plt.rcParams.update({'mathtext.default': 'regular'}) # plot GFP and save figure fig, ax = plt.subplots(figsize=(7, 3)) plot_compare_evokeds(evokeds, axes=ax, linestyles={'Cue A': '-', 'Cue B': '--'}, styles={'Cue A': {"linewidth": 1.5}, 'Cue B': {"linewidth": 1.5}}, ylim=dict(eeg=[-0.1, 4.0]), colors={'Cue A': 'k', 'Cue B': 'crimson'}, show=False) ax.set_title('A) Cue evoked GFP', size=14.0, pad=20.0, loc='left', fontweight='bold', fontname=font) ax.set_xlabel('Time (ms)', labelpad=10.0, font=font, fontsize=12.0) ax.set_xticks(list(np.arange(-.25, 2.55, 0.25)), minor=False) ax.set_xticklabels(list(np.arange(-250, 2550, 250)), fontname=font) ax.set_ylabel(r'$\mu$V', labelpad=10.0, font=font, fontsize=12.0) ax.set_yticks(list(np.arange(0, 5, 1)), minor=False) ax.set_yticklabels(list(np.arange(0, 5, 1)), fontname=font) # annotate the gpf plot and tweak it's appearance for i, val in enumerate(gfp_times.values()): ax.bar(val[0], 3.9, width=val[1], alpha=0.30, align='edge', color=cmap(colors[i]))
evoked_json = json.load(f) evokeds_key = evoked_json['evoked_objects'] # Filter in place if requested if filter_data == 'y': print('Filtering ERPs...') for evoked in evokeds: evoked.filter(0, lcutoff, verbose=False) # Scenes vs. Objects conds = ['scene', 'object'] these_evokeds = [ evokeds[evokeds_key[x]] for x in evokeds_key.keys() if x in conds ] plot_compare_evokeds(these_evokeds, axes='topo', show=True, title='Scenes vs. Objects') # Scenes: Hit vs. Misses (65 are hits) conds = ['scene-hit65', 'scene-miss65'] these_evokeds = [ evokeds[evokeds_key[x]] for x in evokeds_key.keys() if x in conds ] plot_compare_evokeds(these_evokeds, axes='topo', show=True, title='Scene: Hit vs. Miss') # Objcts: Hit vs. Misses (65 are hits) conds = ['object-hit65', 'object-miss65'] these_evokeds = [
# create plot for effect of moderator for elec in [ 'Fp1', 'AFz', 'AF4', 'F4', 'F6', 'F7', 'F5', 'C3', 'CPz', 'Pz', 'Oz', 'CP1', 'PO8', 'PO7' ]: # index of Pz in channels array electrode = elec pick = group_betas_evoked.ch_names.index(electrode) # create figure fig, ax = plt.subplots(figsize=(8, 4)) ax = plot_compare_evokeds({r'Effect of $PBI_{rt}$': group_betas_evoked}, legend='upper center', ylim=dict(eeg=[-2.5, 2.5]), picks=pick, show_sensors='upper right', axes=ax, colors=['k'], show=False) ax[0].axes[0].fill_between( times, # transform values to microvolt upper_b[pick] * 1e6, lower_b[pick] * 1e6, alpha=0.2, color='k') ax[0].axes[0].set_ylabel(r'$\beta$ ($\mu$V)') ax[0].axes[0].axhline(y=0, xmin=-.5, xmax=2.5, color='black',
#'S_Incorrect congr.', 'S_Incorrect incongr.', # '+_Correct congr.', '+_Correct incongr.', #'+_Incorrect congr.', '+_Incorrect incongr.', #'-_Correct congr.', '-_Correct incongr.', #'-_Incorrect congr.', '-_Incorrect incongr.' } evokeds = {key: choice_epochs[key].average() for key in keys} pick = evokeds['S_Correct incongr.'].ch_names.index('Cz') plot_compare_evokeds(evokeds, picks=pick, ylim=dict(eeg=[20, -40])) diff_wave_solo = combine_evoked( [-evokeds['S_Correct incongr.'], evokeds['S_Incorrect incongr.']], weights="equal") diff_wave_pos = combine_evoked( [-evokeds['+_Correct incongr.'], evokeds['+_Incorrect incongr.']], weights="equal") diff_wave_neg = combine_evoked( [-evokeds['-_Correct incongr.'], evokeds['-_Incorrect incongr.']], weights="equal") diff_waves = dict(solo=diff_wave_solo, positive=diff_wave_pos,
# create and plot difference ERP joint_kwargs = \ dict(times=[0.050, 0.200], ts_args=dict(time_unit='s'), topomap_args=dict(time_unit='s')) combine_evoked([ga_incongruent_incorrect_neu, - ga_incongruent_correct_neu, ga_incongruent_incorrect_pos, - ga_incongruent_correct_pos], weights='equal').plot_joint(**joint_kwargs) compare = plot_compare_evokeds(dict(neg_incorrect=ga_incongruent_incorrect_neg, neg_correct=ga_incongruent_correct_neg, pos_incorrect=ga_incongruent_incorrect_pos, pos_correct=ga_incongruent_correct_pos, solo_incorrect=ga_incongruent_incorrect_neu, solo_correct=ga_incongruent_correct_neu), picks='FCz', invert_y=True, ylim=dict(eeg=[-15, 5])) ga_incongruent_incorrect_neu.plot_joint(picks='eeg', title='Neutral') ga_incongruent_incorrect_neu.plot_topomap(times=[0., 0.1, 0.2, 0.3, 0.4], ch_type='eeg', title='neutral') ga_incongruent_incorrect_pos.plot_joint(picks='eeg', title='Positiv') ga_incongruent_incorrect_pos.plot_topomap(times=[0., 0.1, 0.2, 0.3, 0.4], ch_type='eeg', title='Positiv') ga_incongruent_incorrect_neg.plot_joint(picks='eeg', title='Positiv') ga_incongruent_incorrect_neg.plot_topomap(times=[0., 0.1, 0.2, 0.3, 0.4],
tmin=-0.07, tmax=0.63, baseline=(None, 0), reject=reject_criteria, preload=True) print(epochs) #%% # compute evoked response and noise covariance,and plot evoked evoked = epochs.average() print(evoked) #%% title = 'MaasRats' evoked.plot(titles=dict(eeg=title), time_unit='s') evoked.plot_topomap(times=[0.1], size=3., title=title, time_unit='s') #%% S1 = epochs["1"].average() S2 = epochs["2"].average() S3 = epochs["3"].average() S4 = epochs["4"].average() S5 = epochs["5"].average() S6 = epochs["6"].average() all_evokeds = [S1, S2, S3, S4, S5, S6] print(all_evokeds) #%% conditions = ['1', '2', '3'] evokeds = {condition: epochs[condition].average() for condition in conditions} pick = evokeds['1'].ch_names.index('MGB') plot_compare_evokeds(evokeds, picks=pick, ylim=dict(eeg=(-0.05, 0.05))) #%% epochs['1'].plot_image(picks=['MGB']) #try git
epochsSSP['face'].average().plot() epochsSSP['scene'].average().plot() # Generate list of evoked objects from conditions names evokeds = [epochsSSP[name].average() for name in ('scene', 'face')] colors = 'blue', 'red' title = 'Subject \nscene vs face' from mne.viz import plot_evoked_topo, plot_compare_evokeds plot_evoked_topo(evokeds, color=colors, title=title, background_color='w') colors = dict(scene="Crimson", face="CornFlowerBlue") plot_compare_evokeds(evokeds, title=title, show_sensors=True, cmap='viridis', picks=[7]) # When multiple channels are passed, this function combines them all, to get one time course for each condition. #%% y_pred = np.zeros(no_sb * block_len) for sb in range(no_sb): val_indices = range(sb * block_len, (sb + 1) * block_len) # Validation block index stable_blocks_val = stable_blocks[val_indices] y_val = y_stable_blocks[val_indices] stable_blocks_train = np.delete(stable_blocks, val_indices, axis=0) y_train = np.delete(y_stable_blocks, val_indices)
'Control Congruent': control_congruent_sep.copy().crop(tmin=-0.25), 'Control Incongruent': control_incongruent_sep.copy().crop(tmin=-0.25), 'MCI Congruent': mci_congruent_sep.copy().crop(tmin=-0.25), 'MCI Incongruent': mci_incongruent_sep.copy().crop(tmin=-0.25) } evokeds_diff = { 'Diff Control': control_diff_block.copy().crop(tmin=-0.25), 'Diff Mci': mci_diff_block.copy().crop(tmin=-0.25) } # # evokeds_diff = {'Diff Control': control_diff_mix.copy().crop(tmin=-0.25), # 'Diff Mci': mci_diff_mix.copy().crop(tmin=-0.25)} plot_compare_evokeds(evokeds=evokeds_control, picks=['FCC3h'], ylim=dict(eeg=[-5, 5])) fig, ax = plt.subplots(figsize=(6, 4)) plot_compare_evokeds(evokeds=evokeds, picks=['FFC1h'], ylim=dict(eeg=[-7, 7]), legend='lower right', axes=ax) fig.savefig(fname.figures + '/FFC1h_erps_group.pdf', dpi=300) # # ############################################################################### control_erps = [val for val in Control_erps_cong.values()] control_erps.extend([val for val in Control_erps_incong.values()]) control_erps = grand_average(control_erps)
############################################################################### # plot the modulating effect of age on the phase coherence predictor (i.e., # how the effect of phase coherence varies as a function of subject age) # using whole electrode montage and whole scalp by taking the # same physical electrodes across subjects # index of B8 in array electrode = 'B8' pick = group_betas_evoked.ch_names.index(electrode) # create figure fig, ax = plt.subplots(figsize=(7, 4)) ax = plot_compare_evokeds(group_betas_evoked, ylim=dict(eeg=[-3, 3]), picks=pick, show_sensors='upper right', axes=ax) ax[0].axes[0].fill_between( times, # transform values to microvolt upper_b[pick] * 1e6, lower_b[pick] * 1e6, alpha=0.2) plt.plot() ############################################################################### # run analysis on optimized electrode (i.e., electrode showing best fit for # phase-coherence predictor). # find R-squared peak for each subject in the data set
# Since this is a "visual paradigm" it might be best to look at electrodes # located over the occipital lobe, as differences between stimuli (if any) # might easier to spot over visual areas. # Create a dictionary containing the evoked responses conditions = ["Face/A", "Face/B"] evokeds = { condition: limo_epochs[condition].average() for condition in conditions } # concentrate analysis an occipital electrodes (e.g. B11) pick = evokeds["Face/A"].ch_names.index('B11') # compare evoked responses plot_compare_evokeds(evokeds, picks=pick, ylim=dict(eeg=(-15, 7.5))) ############################################################################### # We do see a difference between Face A and B, but it is pretty small. # # # Visualize effect of stimulus phase-coherence # -------------------------------------------- # # Since phase-coherence # determined whether a face stimulus could be easily identified, # one could expect that faces with high phase-coherence should evoke stronger # activation patterns along occipital electrodes. phase_coh = limo_epochs.metadata['phase-coherence'] # get levels of phase coherence
epochs = mne.read_epochs(path) print(epochs.metadata.head()) ############################################################################## # Psycholinguistically relevant word characteristics are continuous. I.e., # concreteness or imaginability is a graded property. In the metadata, # we have concreteness ratings on a 5-point scale. We can show the dependence # of the EEG on concreteness by dividing the data into bins and plotting the # mean activity per bin, color coded. name = "Concreteness" df = epochs.metadata df[name] = pd.cut(df[name], 11, labels=False) / 10 colors = {str(val): val for val in df[name].unique()} epochs.metadata = df.assign(Intercept=1) # Add an intercept for later evokeds = {val: epochs[name + " == " + val].average() for val in colors} plot_compare_evokeds(evokeds, colors=colors, split_legend=True, cmap=(name + " Percentile", "viridis")) ############################################################################## # We observe that there appears to be a monotonic dependence of EEG on # concreteness. We can also conduct a continuous analysis: single-trial level # regression with concreteness as a continuous (although here, binned) # feature. We can plot the resulting regression coefficient just like an # Event-related Potential. names = ["Intercept", name] res = linear_regression(epochs, epochs.metadata[names], names=names) for cond in names: res[cond].beta.plot_joint(title=cond, ts_args=dict(time_unit='s'), topomap_args=dict(time_unit='s')) ############################################################################## # Because the `linear_regression` function also estimates p values, we can --
pos_incorrect = [erps[i]['+_Incorrect incongr.'] for i in range(len(erps))] ga_pos_incorrect = mne.grand_average(pos_incorrect, drop_bads=False) pos_correct = [erps[i]['+_Correct incongr.'] for i in range(len(erps))] ga_pos_correct = mne.grand_average(pos_correct, drop_bads=False) sol_incorrect = [erps[i]['S_Incorrect incongr.'] for i in range(len(erps))] ga_sol_incorrect = mne.grand_average(sol_incorrect, drop_bads=False) sol_correct = [erps[i]['S_Correct incongr.'] for i in range(len(erps))] ga_sol_correct = mne.grand_average(sol_correct, drop_bads=False) pick = ga_neg_incorrect.ch_names.index('FCz') compare = plot_compare_evokeds(dict(neg_incorrect=ga_neg_incorrect, neg_correct=ga_neg_correct, pos_incorrect=ga_pos_incorrect, pos_correct=ga_pos_correct, solo_incorrect=ga_sol_incorrect, solo_correct=ga_sol_correct), picks=pick, ylim=dict(eeg=[9, -9])) topofig1 = ga_neg_incorrect.plot_topomap(times=np.arange(0, .12, .01), outlines='skirt') jointfig = ga_neg_incorrect.plot_joint(picks='eeg') jointfig.savefig("jointplot.png") topofig1.savefig("topofig1.png") compare.savefig("compare.png")
# Add slider section report.add_slider_to_section(figs, section='ERP', title=f'ERP: {cond}', scale=1) plt.close() # Add Select topos to ERP # Oddbal vs. Standard conds = ['oddball', 'standard'] these_evokeds = [ evokeds[evokeds_key[x]] for x in evokeds_key.keys() if x in conds ] fig1 = plot_compare_evokeds(these_evokeds, title='Oddball vs. Standard Trials', axes='topo', show=False, show_sensors=True) fig2 = plot_compare_evokeds(these_evokeds, title='Oddball vs. Standard - Midline Cluster', combine='mean', show=False, show_sensors=True, picks=['Cz', 'CPz', 'Pz', 'POz']) fig3 = plot_compare_evokeds( evokeds[evokeds_key['oddball-standard']], title='Oddball-Standard Difference Wave - Midline Cluster', combine='mean', show=False, show_sensors=True, picks=['Cz', 'CPz', 'Pz', 'POz'])
def run_sensor_stats(): for c in np.arange(len(config.stats_params)): # organise data and analysis parameters dat0_files = config.stats_params[c]['dat0_files'] dat1_files = config.stats_params[c]['dat1_files'] condnames = config.stats_params[c]['condnames'] tmin, tmax = config.stats_params[c]['statwin'] n_permutations = config.stats_params[c]['n_permutations'] p_threshold = config.stats_params[c]['threshold'] tail = config.stats_params[c]['tail'] if tail == 0: p_threshold = p_threshold / 2 tail_x = 1 else: tail_x = tail if 'multi-subject' in config.stats_params[c] and config.stats_params[c]['multi-subject'] == True: # we will run the same analysis on each subject separately nruns = len(dat0_files) ismulti = True else: nruns = 1 ismulti = False results = [] # to store the results later for statrun in np.arange(nruns): if ismulti: # we will run the same analysis on each subject separately dat0, evokeds0, connectivity = collect_data([dat0_files[statrun]],condnames[0],tmin,tmax,ismulti) dat1, evokeds1, _ = collect_data([dat1_files[statrun]],condnames[1],tmin,tmax,ismulti) else: # collect together the data to be compared dat0, evokeds0, connectivity = collect_data(dat0_files,condnames[0],tmin,tmax,ismulti) dat1, evokeds1, _ = collect_data(dat1_files,condnames[1],tmin,tmax,ismulti) alldata = [] # fix threshold to be one-sided if requested if type(p_threshold) != 'dict': # i.e. is NOT TFCE if config.stats_params[c]['stat'] == 'indep': stat_fun = ttest_ind_no_p if len(dat0_files) == 1: # ie is single subject stats df = dat0.data.shape[0] - 1 + dat1.data.shape[0] - 1 else: df = len(dat0_files) - 1 + len(dat1_files) - 1 else: # ie is dependent data, and so is one-sample t test # this will only ever be group data... # If the length of dat0_files and dat1_files are different it'll crash later anyway stat_fun = ttest_1samp_no_p df = len(dat0_files) - 1 threshold_stat = stats.distributions.t.ppf(1. - p_threshold, df) * tail_x else: # i.e. is TFCE threshold_stat = p_threshold # run the stats if config.stats_params[c]['stat'] == 'indep': alldata = [dat0,dat1] cluster_stats = spatio_temporal_cluster_test(alldata, n_permutations=n_permutations, threshold=threshold_stat, tail=tail, stat_fun=stat_fun, n_jobs=1, buffer_size=None, connectivity=connectivity) elif config.stats_params[c]['stat'] == 'dep': # we have to use 1-sample t-tests here so also need to subtract conditions alldata = dat0 - dat1 cluster_stats = spatio_temporal_cluster_1samp_test(alldata, n_permutations=n_permutations, threshold=threshold_stat, tail=tail, stat_fun=stat_fun, n_jobs=1, buffer_size=None, connectivity=connectivity) # extract stats of interest T_obs, clusters, p_values, _ = cluster_stats good_cluster_inds = np.where(p_values < config.stats_params[c]['p_accept'])[0] # tell the user the results print('There are {} significant clusters'.format(good_cluster_inds.size)) if good_cluster_inds.size != 0: print('p-values: {}'.format(p_values[good_cluster_inds])) else: if p_values.any(): print('Minimum p-value: {}'.format(np.min(p_values))) else: print('No clusters found') # some final averaging and tidying if len(evokeds0) == 1: dat0_avg = evokeds0[0].average() dat1_avg = evokeds1[0].average() else: dat0_avg = mne.grand_average(evokeds0) dat1_avg = mne.grand_average(evokeds1) diffcond_avg = mne.combine_evoked([dat0_avg, -dat1_avg], 'equal') # get sensor positions via layout pos = mne.find_layout(evokeds0[0].info).pos ## EVENTUALLY I WILL PUT THE PLOTTING IN A SEPARATE FUNCTION... do_plot = False if do_plot: # loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = T_obs[time_inds, ...].mean(axis=0) # get topography of difference time_shift = evokeds0[0].time_as_index(tmin) # fix windowing shift print('time_shift = {}'.format(time_shift)) sig_times_idx = time_inds + time_shift diff_topo = np.mean(diffcond_avg.data[:,sig_times_idx],axis=1) sig_times = evokeds0[0].times[sig_times_idx] # create spatial mask mask = np.zeros((f_map.shape[0], 1), dtype=bool) mask[ch_inds, :] = True # initialize figure fig, ax_topo = plt.subplots(1, 1, figsize=(10, 3)) # plot average difference and mark significant sensors image, _ = plot_topomap(diff_topo, pos, mask=mask, axes=ax_topo, cmap='RdBu_r', vmin=np.min, vmax=np.max, show=False) # create additional axes (for ERF and colorbar) divider = make_axes_locatable(ax_topo) # add axes for colorbar ax_colorbar = divider.append_axes('right', size='5%', pad=0.05) plt.colorbar(image, cax=ax_colorbar) ax_topo.set_xlabel( 'Mean difference ({:0.3f} - {:0.3f} s)'.format(*sig_times[[0, -1]])) # add new axis for time courses and plot time courses ax_signals = divider.append_axes('right', size='300%', pad=1.2) title = 'Cluster #{0}, {1} sensor'.format(i_clu + 1, len(ch_inds)) if len(ch_inds) > 1: title += "s (mean)" plot_compare_evokeds([dat0_avg, dat1_avg], title=title, picks=ch_inds, axes=ax_signals, colors=None, show=False, split_legend=False, truncate_yaxis='max_ticks') # plot temporal cluster extent ymin, ymax = ax_signals.get_ylim() ax_signals.fill_betweenx((ymin, ymax), sig_times[0], sig_times[-1], color='orange', alpha=0.3) # clean up viz mne.viz.tight_layout(fig=fig) fig.subplots_adjust(bottom=.05) plt.show() results.append({ 'cluster_stats': cluster_stats, 'good_cluster_inds': good_cluster_inds, 'alldata': alldata, 'evokeds0': evokeds0, 'evokeds1': evokeds1 }) # save save_name = op.join(config.stat_path, config.stats_params[c]['analysis_name'] + '.dat') pickle_out = open(save_name,'wb') pickle.dump(results, pickle_out) pickle_out.close()
# # Next, a grand average epoch waveform is generated for each condition. # This is generated using all of the standard (long) fNIRS channels, # as illustrated by the head inset in the top right corner of the figure. # Specify the figure size and limits per chromophore fig, axes = plt.subplots(nrows=1, ncols=len(all_evokeds), figsize=(17, 5)) lims = dict(hbo=[-5, 12], hbr=[-5, 12]) for (pick, color) in zip(['hbo', 'hbr'], ['r', 'b']): for idx, evoked in enumerate(all_evokeds): plot_compare_evokeds({evoked: all_evokeds[evoked]}, combine='mean', picks=pick, axes=axes[idx], show=False, colors=[color], legend=False, ylim=lims, ci=0.95, show_sensors=idx == 2) axes[idx].set_title('{}'.format(evoked)) axes[0].legend(["Oxyhaemoglobin", "Deoxyhaemoglobin"]) # %% # From this figure we observe that the response to the tapping condition # with the right hand appears larger than when no tapping occurred in the # control condition (similar for when tapping occurred with the left hand). # We test if this is the case in the analysis below. # %% # Generate regions of interest
weights = np.repeat(1 / len(subjects), len(subjects)) grand_averages = { val: combine_evoked(factor_evokeds[i][val], weights=weights) for i, val in enumerate(colors) } # pick channel to plot electrodes = ['A19', 'C22', 'B8'] # create figs for electrode in electrodes: fig, ax = plt.subplots(figsize=(7, 4)) plot_compare_evokeds(grand_averages, axes=ax, ylim=dict(eeg=[-12.5, 12.5]), colors=colors, split_legend=True, picks=electrode, cmap=(name + " Percentile", "magma")) plt.show() ################################################################################ # plot individual ERPs for three exemplary subjects # create figs for i, subj in enumerate(evokeds[0:3]): fig, ax = plt.subplots(figsize=(7, 4)) plot_compare_evokeds(subj, axes=ax, title='subject %s' % (i + 2), ylim=dict(eeg=[-20, 20]),
#%% title = 'My first ERP image' evoked.plot(titles=dict(eeg=title), time_unit='s') evoked.plot_topomap(times=[0.1], size=3., title=title, time_unit='s') #%% S1 = epochs["Stimulus/S 1"].average() S2 = epochs["Stimulus/S 2"].average() S3 = epochs["Stimulus/S 3"].average() S4 = epochs["Stimulus/S 4"].average() S5 = epochs["Stimulus/S 5"].average() S6 = epochs["Stimulus/S 6"].average() all_evokeds = [S1, S2, S3, S4, S5, S6] print(all_evokeds) #%% does NOT work! #all_evokeds = [epochs[cond].average() for cond in sorted(event_ids.keys())] #print(all_evokeds) # Then, we can construct and plot an unweighted average of left vs. right # trials this way, too: #mne.combine_evoked( # all_evokeds, weights=[0.5, 0.5, 0.5, -0.5, -0.5, -0.5]).plot_joint(times=[0.1], title='All ERPs') #%% #NEW conditions = ['Stimulus/S 1', 'Stimulus/S 2', 'Stimulus/S 3'] evokeds = {condition:epochs[condition].average() for condition in conditions} pick = evokeds['Stimulus/S 1'].ch_names.index('Cz') plot_compare_evokeds(evokeds, picks=pick, ylim=dict(eeg=(-5, 2))) #%% epochs['Stimulus/S 1'].plot_image(picks=['Cz'])
color='r') axs[ii].set(title=key) if ii == 0: axs[ii].set(xlabel='Time (ms)', ylabel='t-value') else: axs[ii].legend(numpoints=1, facecolor=None, **leg_kwargs) box_off(axs[ii]) axs[ii].axvline(c='k', linewidth=0.5, zorder=0) axs[ii].get_xticklabels()[0].set(horizontalalignment='right') fig.canvas.set_window_title(titles_comb[gi]) fig.tight_layout() fig.savefig(op.join(fig_dir, '%s_%smos_%d_TFCE.png' % (analysis, group, lpf)), dpi=300, format='png') for hi, hem in enumerate(sensors.keys()): print(' Plotting %s data...' % hem) picks = [ch_names.index(jj) for jj in sensors[hem]] hs = plot_compare_evokeds(evokeds=evoked_dict, picks=picks, colors=colors, ci=.95, title=titles_comb[gi] + ' Oddball Stimuli') for h, chs in zip(hs, ['mag', 'grads']): h.savefig(op.join( fig_dir, '%s_%smos_%d_%s-%s.png' % (analysis, group, lpf, hem, chs)), dpi=300, format='png')
lower_t = lower_t.reshape((n_channels, n_times)) upper_t = upper_t.reshape((n_channels, n_times)) ############################################################################### # plot mean beta parameter for phase coherence and 95% # confidence interval for the electrode showing the strongest effect (i.e., C1) # index of C1 in array electrode = 'C1' pick = ga_phase_coherence.ch_names.index(electrode) # create figure fig, ax = plt.subplots(figsize=(7, 4)) plot_compare_evokeds(ga_phase_coherence, ylim=dict(eeg=[-1.5, 3.5]), picks=pick, show_sensors='upper right', colors=['k'], axes=ax) ax.fill_between( times, # transform values to microvolt upper_b[pick] * 1e6, lower_b[pick] * 1e6, color=['k'], alpha=0.2) plt.plot() ############################################################################### # compute one sample t-test on phase coherence betas # estimate t-values
# create additional axes (for ERF and colorbar) divider = make_axes_locatable(ax_topo) # add axes for colorbar ax_colorbar = divider.append_axes('right', size='5%', pad=0.05) plt.colorbar(image, cax=ax_colorbar) ax_topo.set_xlabel( 'Averaged F-map ({:0.3f} - {:0.3f} s)'.format(*sig_times[[0, -1]])) # add new axis for time courses and plot time courses ax_signals = divider.append_axes('right', size='300%', pad=1.2) title = 'Cluster #{0}, {1} sensor'.format(i_clu + 1, len(ch_inds)) if len(ch_inds) > 1: title += "s (mean)" plot_compare_evokeds(evokeds, title=title, picks=ch_inds, axes=ax_signals, colors=colors, linestyles=linestyles, show=False, split_legend=True, truncate_yaxis='max_ticks') # plot temporal cluster extent ymin, ymax = ax_signals.get_ylim() ax_signals.fill_betweenx((ymin, ymax), sig_times[0], sig_times[-1], color='orange', alpha=0.3) # clean up viz mne.viz.tight_layout(fig=fig) fig.subplots_adjust(bottom=.05) plt.show() ############################################################################### # Exercises # ----------
# add axes for colorbar ax_colorbar = divider.append_axes('right', size='5%', pad=0.05) plt.colorbar(image, cax=ax_colorbar) ax_topo.set_xlabel( 'Averaged F-map ({:0.3f} - {:0.3f} s)'.format(*sig_times[[0, -1]])) # add new axis for time courses and plot time courses ax_signals = divider.append_axes('right', size='300%', pad=1.2) title = 'Cluster #{0}, {1} sensor'.format(i_clu + 1, len(ch_inds)) if len(ch_inds) > 1: title += "s (mean)" plot_compare_evokeds(group_t['phase-coherence-scaled'], title=title, picks=ch_inds, combine='mean', axes=ax_signals, show=False, split_legend=True, truncate_yaxis='max_ticks') # plot temporal cluster extent ymin, ymax = ax_signals.get_ylim() ax_signals.fill_betweenx((ymin, ymax), sig_times[0], sig_times[-1], color='orange', alpha=0.3) ax_signals.set_ylabel('F-value') # clean up viz tight_layout(fig=fig)
# create additional axes (for ERF and colorbar) divider = make_axes_locatable(ax_topo) # add axes for colorbar ax_colorbar = divider.append_axes('right', size='5%', pad=0.05) plt.colorbar(image, cax=ax_colorbar) ax_topo.set_xlabel( 'Averaged F-map ({:0.3f} - {:0.3f} s)'.format(*sig_times[[0, -1]])) # add new axis for time courses and plot time courses ax_signals = divider.append_axes('right', size='300%', pad=1.2) title = 'Cluster #{0}, {1} sensor'.format(i_clu + 1, len(ch_inds)) if len(ch_inds) > 1: title += "s (mean)" plot_compare_evokeds(evokeds, title=title, picks=ch_inds, axes=ax_signals, colors=colors, linestyles=linestyles, show=False, split_legend=True, truncate_yaxis='max_ticks') # plot temporal cluster extent ymin, ymax = ax_signals.get_ylim() ax_signals.fill_betweenx((ymin, ymax), sig_times[0], sig_times[-1], color='orange', alpha=0.3) # clean up viz mne.viz.tight_layout(fig=fig) fig.subplots_adjust(bottom=.05) plt.show() ############################################################################### # Exercises # ----------
def plot_temporal_clusters(good_cluster_inds, evokeds, T_obs, clusters, times, info): colors = {"low": "crimson", "high": "steelblue"} # linestyles = {"low": "-", "high": "--"} # # loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = T_obs[time_inds, ...].mean(axis=0) # get signals at the sensors contributing to the cluster sig_times = times[time_inds] # create spatial mask mask = np.zeros((f_map.shape[0], 1), dtype=bool) mask[ch_inds, :] = True # initialize figure fig, ax_topo = plt.subplots(1, 1, figsize=(10, 3)) # plot average test statistic and mark significant sensors f_evoked = EvokedArray(f_map[:, np.newaxis], info, tmin=0) f_evoked.plot_topomap( times=0, mask=mask, axes=ax_topo, cmap="Reds", vmin=np.min, vmax=np.max, show=False, colorbar=False, mask_params=dict(markersize=10), scalings=dict(eeg=1, mag=1, grad=1), res=240, ) image = ax_topo.images[0] # create additional axes (for ERF and colorbar) divider = make_axes_locatable(ax_topo) # add axes for colorbar ax_colorbar = divider.append_axes("right", size="5%", pad=0.05) plt.colorbar(image, cax=ax_colorbar) ax_topo.set_xlabel( "Averaged F-map ({:0.3f} - {:0.3f} s)".format(*sig_times[[0, -1]])) # add new axis for time courses and plot time courses ax_signals = divider.append_axes("right", size="300%", pad=1.2) title = "Cluster #{0}, {1} sensor".format(i_clu + 1, len(ch_inds)) if len(ch_inds) > 1: title += "s (mean)" plot_compare_evokeds( evokeds, title=title, picks=ch_inds, axes=ax_signals, colors=colors, # linestyles=linestyles, show=False, split_legend=True, truncate_yaxis="auto", ) # plot temporal cluster extent ymin, ymax = ax_signals.get_ylim() ax_signals.fill_betweenx( (ymin, ymax), sig_times[0], sig_times[-1], color="orange", alpha=0.3, ) # clean up viz tight_layout(fig=fig) fig.subplots_adjust(bottom=0.05) plt.show()
def test_plot_compare_evokeds(): """Test plot_compare_evokeds.""" evoked = _get_epochs().average() # test defaults figs = plot_compare_evokeds(evoked) assert len(figs) == 3 # test picks, combine, and vlines (1-channel pick also shows sensor inset) picks = ['MEG 0113', 'mag'] + 2 * [['MEG 0113', 'MEG 0112']] + [[0, 1]] vlines = [[0.1, 0.2], []] + 3 * ['auto'] combine = [None, 'mean', 'std', None, lambda x: np.min(x, axis=1)] title = ['MEG 0113', '(mean)', '(std. dev.)', '(GFP)', 'MEG 0112'] for _p, _v, _c, _t in zip(picks, vlines, combine, title): fig = plot_compare_evokeds(evoked, picks=_p, vlines=_v, combine=_c) assert fig[0].axes[0].get_title().endswith(_t) # test passing more than one evoked red, blue = evoked.copy(), evoked.copy() red.data *= 1.5 blue.data /= 1.5 evoked_dict = {'aud/l': blue, 'aud/r': red, 'vis': evoked} huge_dict = {'cond{}'.format(i): ev for i, ev in enumerate([evoked] * 11)} plot_compare_evokeds(evoked_dict) # dict plot_compare_evokeds([[red, evoked], [blue, evoked]]) # list of lists figs = plot_compare_evokeds({'cond': [blue, red, evoked]}) # dict of list # test that confidence bands are plausible for fig in figs: extents = fig.axes[0].collections[0].get_paths()[0].get_extents() xlim, ylim = extents.get_points().T assert np.allclose(xlim, evoked.times[[0, -1]]) line = fig.axes[0].lines[0] xvals = line.get_xdata() assert np.allclose(xvals, evoked.times) yvals = line.get_ydata() assert (yvals < ylim[1]).all() assert (yvals > ylim[0]).all() plt.close('all') # test other CI args def ci_func(array): return array.mean(axis=0, keepdims=True) * np.array([[0.5], [1.5]]) ci_types = (None, False, 0.5, ci_func) for _ci in ci_types: fig = plot_compare_evokeds({'cond': [blue, red, evoked]}, ci=_ci)[0] if _ci in ci_types[2:]: assert np.any([ isinstance(coll, PolyCollection) for coll in fig.axes[0].collections ]) # make sure we can get a CI even for single conditions fig = plot_compare_evokeds(evoked, picks='eeg', ci=ci_func)[0] assert np.any( [isinstance(coll, PolyCollection) for coll in fig.axes[0].collections]) with pytest.raises(TypeError, match='"ci" must be None, bool, float or'): plot_compare_evokeds(evoked, ci='foo') # test sensor inset, legend location, and axis inversion & truncation plot_compare_evokeds(evoked_dict, invert_y=True, legend='upper left', show_sensors='center', truncate_xaxis=False, truncate_yaxis=False) plot_compare_evokeds(evoked, ylim=dict(mag=(-50, 50)), truncate_yaxis=True) plt.close('all') # test styles plot_compare_evokeds(evoked_dict, colors=['b', 'r', 'g'], linestyles=[':', '-', '--'], split_legend=True) style_dict = dict(aud=dict(alpha=0.3), vis=dict(linewidth=3, c='k')) plot_compare_evokeds(evoked_dict, styles=style_dict, colors={'aud/r': 'r'}, linestyles=dict(vis='dotted'), ci=False) plot_compare_evokeds(evoked_dict, colors=list(range(3))) plt.close('all') # test colormap cmap = get_cmap('viridis') plot_compare_evokeds(evoked_dict, cmap=cmap, colors=dict(aud=0.4, vis=0.9)) plot_compare_evokeds(evoked_dict, cmap=cmap, colors=dict(aud=1, vis=2)) plot_compare_evokeds(evoked_dict, cmap=('cmap title', 'inferno'), linestyles=['-', ':', '--']) plt.close('all') # test combine match = 'combine must be an instance of None, callable, or str' with pytest.raises(TypeError, match=match): plot_compare_evokeds(evoked, combine=["mean", "gfp"]) plt.close('all') # test warnings with pytest.warns(RuntimeWarning, match='in "picks"; cannot combine'): plot_compare_evokeds(evoked, picks=[0], combine='median') plt.close('all') # test errors with pytest.raises(TypeError, match='"evokeds" must be a dict, list'): plot_compare_evokeds('foo') with pytest.raises(ValueError, match=r'keys in "styles" \(.*\) must '): plot_compare_evokeds(evoked_dict, styles=dict(foo='foo', bar='bar')) with pytest.raises(ValueError, match='colors in the default color cycle'): plot_compare_evokeds(huge_dict, colors=None) with pytest.raises(TypeError, match='"cmap" is specified, then "colors"'): plot_compare_evokeds(evoked_dict, cmap='Reds', colors={ 'aud/l': 'foo', 'aud/r': 'bar', 'vis': 'baz' }) plt.close('all') for kwargs in [dict(colors=[0, 1]), dict(linestyles=['-', ':'])]: match = r'but there are only \d* (colors|linestyles). Please specify' with pytest.raises(ValueError, match=match): plot_compare_evokeds(evoked_dict, **kwargs) for kwargs in [dict(colors='foo'), dict(linestyles='foo')]: match = r'"(colors|linestyles)" must be a dict, list, or None; got ' with pytest.raises(TypeError, match=match): plot_compare_evokeds(evoked_dict, **kwargs) for kwargs in [dict(colors=dict(foo='f')), dict(linestyles=dict(foo='f'))]: match = r'If "(colors|linestyles)" is a dict its keys \(.*\) must ' with pytest.raises(ValueError, match=match): plot_compare_evokeds(evoked_dict, **kwargs) for kwargs in [dict(legend='foo'), dict(show_sensors='foo')]: with pytest.raises(ValueError, match='not a legal MPL loc, please'): plot_compare_evokeds(evoked_dict, **kwargs) with pytest.raises(TypeError, match='an instance of list or tuple'): plot_compare_evokeds(evoked_dict, vlines='foo') with pytest.raises(ValueError, match='"truncate_yaxis" must be bool or '): plot_compare_evokeds(evoked_dict, truncate_yaxis='foo') plt.close('all') # test axes='topo' figs = plot_compare_evokeds(evoked_dict, axes='topo', legend=True) for fig in figs: assert len(fig.axes[0].lines) == len(evoked_dict) # test with (fake) CSD data csd = _get_epochs(picks=np.arange(315, 320)).average() # 5 EEG chs for entry in csd.info['chs']: entry['coil_type'] = FIFF.FIFFV_COIL_EEG_CSD entry['unit'] = FIFF.FIFF_UNIT_V_M2 plot_compare_evokeds(csd, picks='csd', axes='topo') # old tests red.info['chs'][0]['loc'][:2] = 0 # test plotting channel at zero plot_compare_evokeds([red, blue], picks=[0], ci=lambda x: [x.std(axis=0), -x.std(axis=0)]) plot_compare_evokeds([list(evoked_dict.values())], picks=[0], ci=_parametric_ci) # smoke test for tmin >= 0 (from mailing list) red.crop(0.01, None) assert len(red.times) > 2 plot_compare_evokeds(red) # plot a flat channel red.data = np.zeros_like(red.data) plot_compare_evokeds(red) # smoke test for one time point (not useful but should not fail) red.crop(0.02, 0.02) assert len(red.times) == 1 plot_compare_evokeds(red) # now that we've cropped `red`: with pytest.raises(ValueError, match='not contain the same time instants'): plot_compare_evokeds(evoked_dict) plt.close('all')
# Add slider section report.add_slider_to_section(figs, section='ERP', title=f'ERP: {cond}', scale=1) plt.close() # Add Select topos to ERP # Novel vs. repeated conds = ['repeat', 'novel'] these_evokeds = \ [evokeds[evokeds_key[x]] for x in evokeds_key.keys() if x in conds] fig1 = plot_compare_evokeds(these_evokeds, title='Novel vs. Repeat Trials', axes='topo', show=False, show_sensors=True) fig2 = plot_compare_evokeds(these_evokeds, title='Novel vs. Repeat Trials - Midline', axes='topo', show=False, show_sensors=True, picks=['Fz', 'Cz', 'Pz', 'Oz']) captions = ['Novel vs. Repeat Trials', 'Novel vs. Repeat Trials - Midline'] figs = [fig1[0], fig2[0]] report.add_slider_to_section(figs, section='ERP', captions=captions, title='ERP: Topo - Novel vs. Repeat', scale=1.5)