def reg_single_channel_wrap(model, subs=cfg.subs, bands=cfg.bands, alpha=cfg.alpha, name=''): # load data df = cf.load_df(f"reg_{model['tag']}", bands=bands, subs=subs) # filter out not significant df = df.query(f'p<{alpha}') time_start = time.time() for i in range(len(df)): cf.display_progress( f"{df.iloc[i]['sub']} {df.iloc[i]['ch_name']} {df.iloc[i]['band']}", i, len(df), time_start) for predictor in model['predictors_stepwise']: if df.iloc[i]['p' + predictor] < alpha and df.iloc[i][ 'r2' + predictor] > 0: band = cfg.bands[[b['name'] for b in cfg.bands ].index(df.iloc[i]['band'])] reg_single_channel(df.iloc[i]['sub'], df.iloc[i]['ch_name'], band, model, plot=False) cf.concatenate_pdfs(cf.check_path( ['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]), 'temp', f"single_channel_reg-{model['tag']}{name}.pdf", remove=True)
def electrode_positions(subs=cfg.subs): """ Make one figure per channel with the position of the channel Concatenate for each subject """ print("\n======== electrode positions ======================================\n") FiguresPath =cf.check_path(['..','Figures' , 'overview' + cfg.out ]) # iterate over subjects for sub in subs: cf.print_d(f'Electrode positions for {sub}') # load subject params SP = cf.sub_params(sub) for iCh, ChName in enumerate(SP['ChNames']): fig, ax = plt.subplots(1,1,figsize=(6,2)) pl.clear_axes(np.array([ax])) fig.suptitle(f"{sub} {ChName}") pl.channel_position_plot(ax,SP['coords'],iCh) fig_name = os.path.join(FiguresPath,f"elec_positions_{sub}_{ChName}_temp.pdf") fig.savefig(fig_name, format='pdf') plt.close() cf.concatenate_pdfs(FiguresPath,'temp',f"elec_positions_{sub}.pdf", remove=True)
def subject_overview(subs = cfg.subs, bands = cfg.bands, EpochsSetups = cfg.EpochsSetups, avg = True, TrialWise = True, key = None, picks = 'good'): """ Make one figure per channel with channel position and one evoked plot per band Parameters ---------- key : str metadata key to plot separate traces by metadata value """ print("\n======== subject overview =========================================\n") # iterate over subjects for sub in subs: # load subject params SP = cf.sub_params(sub) # preload raw data for all bands epochs = [] iterator = product(enumerate(bands),enumerate(EpochsSetups)) for i, ((iBand, band),(iEp, EpochsSetup)) in enumerate(iterator): cf.print_d(f"{sub}, loading {band['name']} epochs...") # get list of channels PicksList = cf.get_picks(SP, picks, band = band) if PicksList == []: continue # epochs (phase epochs are complex and cannot be resampled) try: epochs += [cf.load_epochs(sub, band, EpochsSetup, picks = PicksList).resample(100)] except: epochs += [cf.load_epochs(sub, band, EpochsSetup, picks = PicksList)] # iterate over channels, one figure per channel TimeStart = time.time() for iCh, ChName in enumerate(PicksList): cf.display_progress(f"{sub}, {ChName}", iCh, len(PicksList),TimeStart) channel_overview(sub, ChName, bands, EpochsSetups, EpochsList=epochs, key=key, plot = False, save = True, temp=True) # concatenate figures subject wise FileName = f"{sub}_band-{band['name']}_{picks}_overview.pdf" FiguresPath = cf.check_path(['..', 'Figures', 'overview' + cfg.out]) cf.concatenate_pdfs(FiguresPath, 'temp', FileName, remove = True) # concatenate for all subjects FileName = f"band-{band['name']}_{picks}_overview.pdf" FiguresPath = cf.check_path(['..', 'Figures', 'overview' + cfg.out]) cf.concatenate_pdfs(FiguresPath, 'sub', FileName, remove = False)
def rejection_figure(SP, kept, stats, thresholds, save=True, plot=False): """ Make rejection summary figure for single subject """ #create figure fig, ax = plt.subplots(2, 1, figsize=(7, 7)) fig.suptitle( f"{SP['sub']}, rejected {np.sum(~kept)}/{len(kept)}, {int(100*np.sum(~kept)/len(kept))}%", fontsize=15) # rejected channel positions pl.brain_plot(ax[0], SP['ChInfo']['coords'], 1. * (~kept), mask=kept, mode='symmetric', interval=[0, 1]) # scatter with rejection summary pl.scatter_plot(ax[1], stats[0], stats[1], stats[2], colorbar='s', mask=kept, ylabel='std(dVdt)', xlabel='std(V)', vlines=thresholds[0], hlines=thresholds[1]) # save figure FigName = os.path.join(cf.check_path([SP['FiguresPath'], 'rejection']), f"{SP['sub']}.pdf") if save: fig.savefig(FigName, format='pdf', dpi=100) if plot: plt.show() else: plt.close()
def reg_maps(model, predictors=[''], subs=cfg.subs, bands=cfg.bands, alpha=cfg.alpha, filter_tag='', fdr=False, plot=True, save=True, concat=True, time=True): """ Plot brain maps for variables (p_value, r2, ...) stored in files for each band Parameters ---------- alpha : float level of significance (leave out p>alpha) subs : list of str list of subjects to include f.e. [sub-01, sub-02] bands : list of dict list of bands to include """ print(f"\nBand comparison brain map for reg {model['tag']}") if predictors == 'all': predictors = [''] + model['predictors'] # load data df = cf.load_df(f"reg_{model['tag']}", bands=bands, subs=subs) # get total number of channels L = len(df[df['band'] == bands[0]['name']]) # filter out regressions with negative score df = df.query(f'r2>0 and p<{alpha}') if time: conditions, keys = [], [] for p in predictors: conditions += 2 * ['p' + p] keys += ['r2' + p, 't' + p] else: conditions = ['p' + p for p in predictors] keys = ['r2' + p for p in predictors] # loop over figures for i, (k, c) in enumerate(zip(keys, conditions)): print(i, k) fig, ax = plt.subplots(len(bands), 2, figsize=(12, 3 * len(bands)), gridspec_kw={'width_ratios': [3, 1]}) if len(bands) == 1: ax = np.array([ax]) fig.suptitle(fr"reg {model['tag']}, {k}, {c} $\leq {alpha}$", fontsize=20) for i_band, band in enumerate(bands): df_band = df[df['band'] == band['name']] if len(df_band) == 0: continue # extract data to plot x = df_band[k] coords = np.array([c for c in df_band['coords'].values]) pl.brain_plot(ax[i_band, 0], coords, x, ylabel=band['name'], mask=(df_band[c] > alpha), colorbar='' + (i_band == (len(bands) - 1)) * k, mode='interval', interval=[max(0, np.min(df[k])), np.max(df[k])]) s = df_band[df_band[c] < alpha][k] x = np.linspace(0, np.max(df[k]), 20) h, x = np.histogram(s, bins=x, density=False) ax[i_band, 1].bar(x[:-1] + .5 * (x[1] - x[0]), h, width=.8 * (x[1] - x[0])) ax[i_band, 1].set_xlabel(k) ax[i_band, 1].spines['right'].set_visible(False) ax[i_band, 1].spines['top'].set_visible(False) ax[i_band, 1].tick_params(axis='both', which='both', size=0, labelsize=9) if k != 'r2': L = len(df) ax[i_band, 1].set_title(f"{np.sum(h)}/{L} {int(100*np.sum(h)/L)}%") fig.subplots_adjust(left=0.1, right=0.9, hspace=0.5) if save: fig_name = os.path.join( cf.check_path( ['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]), f"brain_map_reg_{model['tag']}_{str(i).zfill(2)}{'_temp'*concat}.pdf" ) fig.savefig(fig_name, format='pdf', dpi=100) if plot: plt.show() else: plt.close() if save and concat: cf.concatenate_pdfs(cf.check_path( ['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]), 'temp', f"brain_map_reg-{model['tag']}.pdf", remove=True)
def reg_statistics(model, predictors=[''], subs=cfg.subs, bands=cfg.bands, alpha=cfg.alpha, filter_tag='', plot=True, save=True): # load data df = cf.load_df(f"reg_{model['tag']}", bands=bands, subs=subs) L = len(df) # filter out regressions with negative score df = df.query(f'r2>0 and p<{alpha}') if predictors == 'all': predictors = [''] + model['predictors'] keys = ['p' + p for p in predictors] conditions = ['r2' + p for p in predictors] fig, ax = plt.subplots(len(keys), 3, figsize=(12, 3 * len(keys)), gridspec_kw={'width_ratios': [1, 2, 0.5]}) if len(keys) == 1: ax = np.array([ax]) fig.suptitle(f"Regression stats summary", fontsize=15) colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(bands))) for i, (k, c) in enumerate(zip(keys, conditions)): # scatter r2 vs p ------------------------------------------------------------- for i_band, band in enumerate(bands): ax[i, 0].scatter(df[df['band'] == band['name']][k], df[df['band'] == band['name']][c], c=[colors[i_band]], alpha=0.3) ax[i, 0].set_xlabel(k) ax[i, 0].set_ylabel(c) ax[i, 0].axvline(alpha, color='k', linewidth=0.5) ax[i, 0].axhline(0, color='k', linewidth=0.5) ax[i, 0].spines['right'].set_visible(False) ax[i, 0].spines['top'].set_visible(False) ax[i, 0].tick_params(axis='both', which='both', size=0, labelsize=9) # number of significant channels ---------------------------------------------- n = [] for sub in subs: # load subject params dp = cf.sub_params(sub) # significant channels for subjec-band pair n_sub = [] # iterate over bands ----------------------------------------------- for i_band, band in enumerate(bands): n_sub += [ np.sum( np.array(df[(df['sub'] == sub) & (df['band'] == band['name'])][k]) < alpha) ] # go to next band -------------------------------------------------- n += [n_sub] # go to next subject ====================================================== n = np.array(n).T # width and positions of bars width = 0.8 / len(bands) x = np.arange(len(subs)) colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(bands))) for i_band, band in enumerate(bands): ax[i, 1].bar(x + i_band * width, n[i_band], width, color=colors[i_band]) ax[i, 2].bar(i_band * width, np.sum(n[i_band]), width, label=band['name'], color=colors[i_band]) ax[i, 1].set_ylabel("# significant channels") ax[i, 1].set_xticks(np.arange(len(subs)) + 0.4) ax[i, 1].set_xticklabels(subs, rotation=45) ax[i, 1].spines['right'].set_visible(False) ax[i, 1].spines['top'].set_visible(False) ax[i, 1].tick_params(axis='both', which='both', size=0, labelsize=9) ax[i, 2].set_xticks([0.4]) ax[i, 2].set_xlim([-0.2, 1]) ax[i, 2].set_xticklabels(['Total']) ax[i, 2].spines['right'].set_visible(False) ax[i, 2].spines['top'].set_visible(False) ax[i, 2].tick_params(axis='both', which='both', size=0, labelsize=9) if i > 0: L = len(df) ax[i, 2].set_title(f"{np.sum(n)}/{L} {int(100*np.sum(n)/L)}%") ax[0, 2].legend(frameon=False, loc=(1, 0.2), fontsize=9) fig.subplots_adjust(left=0.1, right=0.9, wspace=0.3, hspace=0.5) # save figure fig_name = os.path.join( cf.check_path(['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]), f"stats_reg_{model['tag']}.pdf") if save: fig.savefig(fig_name, format='pdf', dpi=100) if plot: plt.show() else: plt.close()
def spike_detection(sub, ch_name, tw): dp = cf.sub_params(sub) # load epochs filename = os.path.join(dp['derivatives_path'], f'{sub}_raw.fif') raw = mne.io.read_raw_fif(filename, preload=True).crop(tmin=tw[0], tmax=tw[1]) amp = np.array([raw.get_data(picks=ch_name)]) t = np.linspace(tw[0], tw[1], amp.shape[-1]) # compute wavelets f = np.arange(5, 150, 2) power = np.squeeze( mne.time_frequency.tfr_array_morlet(amp, sp.srate, f, n_cycles=f / 2., output='power')[0]) power = power / power.std(axis=-1)[:, np.newaxis] #*f[:,np.newaxis] amp = np.squeeze(amp) timewindowsize = 0.1 # s d = int(timewindowsize * sp.srate) C = [] for i in range(len(t) - d): cf.print_d(f"{i/(len(t) - d)}") corr = np.corrcoef(power[:, i:i + d]) corr = corr[np.triu_indices_from(corr, k=1)] C += [corr] C = np.array(C).T fig, ax = plt.subplots(4, 1, figsize=(6, 6)) fig.suptitle(f'{sub} {ch_name}') coords = dp['coords'][dp['ch_names'].index(ch_name)] pl.channel_position_plot(ax[0], [coords], 0) pl.trace_plot(ax[1], t, amp, xlims=[tw[0] + 0.5, tw[1] - 0.5], ylabel='V (uV)') pl.imshow_plot(ax[2], power, title='', ylabel='f (Hz)', xlims=[tw[0] + 0.5, tw[1] - 0.5], ylims=f, colorbar='power (std)') pl.trace_plot(ax[3], t[:-d], C, xlims=[tw[0] + 0.5, tw[1] - 0.5], ylabel='correlation', xlabel='t (s)', plot_std=True, plot_p595=True, mode='avg') fig_name = os.path.join(cf.check_path(['..', 'Figures', 'spikes']), f'{sub}_{ch_name}_{int(tw[0])}.pdf') fig.savefig(fig_name, format='pdf') plt.close()
def num_significant_channels(key, test, tag, split=None, alpha=sp.alpha, subs=sp.subject_list, bands=sp.bands): """ Make a bar plot with number of significant channels per subject per band for some test or regression Parameters ---------- key : str name of the column to extract test : str name of the test/regression that works as a label for files queries : dict generated with cf.compose_queries, contains mne queries, file tag, queries list split : int or str if int divide the time window into 'split' chunks and run one test in each if string separate epochs by values of metadata column 'split', f.ex. split = 'w_position' run the test for each word position alpha : float level of significance (leave out p>alpha) subs : list of str list of subjects to include f.e. [sub-01, sub-02] bands : list of dict list of bands to include """ print(f"\n{test} {tag} summary figure") df = cf.load_df(test + '_' + tag) if split == None: labels = [''] # no split elif isinstance(split, int): labels = list(np.unique(df['tw'].to_numpy())) # split by time windows elif isinstance(split, str): labels = list(np.unique(df[split].to_numpy())) # split by conditions num_plots = len(labels) fig, ax = plt.subplots(num_plots, 1, figsize=(len(subs), 3 * num_plots), sharex=True) fig.suptitle(fr"{test} {tag}, {key} $\leq {alpha}$") if split == None: ax = np.array([ax]) # loop over plots for i_plot, label in enumerate(labels): # number of significant channels n = [] for sub in subs: # load subject params dp = cf.sub_params(sub) # significant channels for subjec-band pair n_sub = [] # iterate over bands ----------------------------------------------- for i_band, band in enumerate(bands): if split == None: n_sub += [ np.sum( np.array(df[(df['sub'] == sub) & ( df['band'] == band['name'])][key]) < alpha) ] title = '' elif isinstance(split, int): n_sub += [ np.sum( np.array(df[ (df['sub'] == sub) & (df['band'] == band['name']) & ([x == label for x in df['tw'].to_numpy()])] [key]) < alpha) ] title = str(label) + ' s' elif isinstance(split, str): n_sub += [ np.sum( np.array(df[(df['sub'] == sub) & (df['band'] == band['name']) & (df[split] == label)][key]) < alpha) ] title = f"{split} = {label}" # go to next band -------------------------------------------------- n += [n_sub] # go to next subject ====================================================== n = np.array(n).T # width and positions of bars width = 0.8 / len(bands) x = np.arange(len(subs)) colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(bands))) for i_band, band in enumerate(bands): ax[i_plot].bar(x + i_band * width, n[i_band], width, label=band['name'], color=colors[i_band]) ax[i_plot].set_ylabel("# significant channels") ax[i_plot].set_title(title) ax[i_plot].set_xticks(np.arange(len(subs)) + 0.4) ax[i_plot].set_xticklabels(subs) ax[i_plot].spines['right'].set_visible(False) ax[i_plot].spines['top'].set_visible(False) ax[i_plot].tick_params(axis='both', which='both', size=0, labelsize=9) ax[i_plot].legend(frameon=False, loc=(1, 0.2), fontsize=9) fig.subplots_adjust(right=0.8) # save figure fig_name = os.path.join(cf.check_path(['..', 'Figures', test + sp.out]), f"summary_{test}_{tag}_{key}.pdf") fig.savefig(fig_name, format='pdf', dpi=100) if sp.plot: plt.show() plt.close()
def band_comparison_matrix(key, file_tag, path, title='', label='', subs=sp.subject_list, bands=sp.bands, log10=False): """ Compare variables (p_value, r2, ...) between bands with scatter plots Parameters ---------- key : str name of the column to extract file_tag : str name of the figure will be brain_map_{file_tag}.pdf subs : list of str list of subjects to include f.e. [sub-01, sub-02] bands : list of dict list of bands to include """ print(f'\nBand comparison matrix for {file_tag}') if len(bands) == 1: sys.exit('At least 2 bands needed only 1 was passed') df = cf.load_df(file_tag, subs=subs, bands=bands) # fig 2: comparison accros bands --------------------------------------------------------------------- fig, ax = plt.subplots(len(bands) - 1, len(bands) - 1, figsize=(2.5 * (len(bands) - 1), 2.5 * (len(bands) - 1))) fig.suptitle(title, fontsize=20) clear_axes(ax) for i, band in enumerate(bands[:-1]): # data for first band x = df[df['band'] == band['name']][key] if log10: x = -np.log10(x) ax[-1, i].set_xlabel(band['name']) ax[i, 0].set_ylabel(bands[i + 1]['name']) # comparison across bands for j in range(i, len(bands) - 1): y = df[df['band'] == bands[j + 1]['name']][key] if log10: y = -np.log10(y) ax[j, i].scatter(x, y) #ax[j,i].hist2d(x,y,bins=np.linspace(min(x.min(),y.min()),max(x.max(),y.max()),10),cmap='Reds') # draw diagonal line ax[j, i].axis('equal') ax[j, i].plot([0, 1], [0, 1], 'k--', transform=ax[j, i].transAxes) ax[j, i].spines['left'].set_visible(True) ax[j, i].spines['bottom'].set_visible(True) #ax[i,j].set_xlim([0,np.log10(sp.n_permutations)]) #ax[i,j].set_ylim([0,np.log10(sp.n_permutations)]) #ax[i,j].set_xticks([0,1,2]) #ax[i,j].set_yticks([0,1,2]) fig.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95, wspace=0.3, hspace=0.3) # save figure fig_name = os.path.join(cf.check_path(path), f"matrix_{file_tag}.pdf") fig.savefig(fig_name, format='pdf', dpi=100) if sp.plot: plt.show() plt.close()
def ttest(EpochsSetups, EOIlabel, split=None, subs=cfg.subs, bands=cfg.bands, picks='good', alpha=cfg.alpha, paired=False, PopMean=0, alternative='greater', Bonferroni=False, fdr=True, figure=True): """ Run ttest on epochs looping over subjects and bands Use split to run tests on different subsets of the data Parameters ---------- EpochsSetups : list of dict split : str or None separate epochs by values of metadata column 'split', f.ex. split = 'w_position' run the test independently for each word position subs : list of str subject list bands : list of dict Outputs ------- """ print( f"\n======== t-test ==================================================\n {EOIlabel}\n" ) from scipy.stats import ttest_ind, ttest_1samp # ITERATE SUBJECT LIST AND BAND LIST ======================================= TimeStart = time.time() iterator = list(product(enumerate(bands), enumerate(subs))) for i, ((iBand, band), (iSub, sub)) in enumerate(iterator): cf.display_progress(f"{sub} {band['name']}", i, len(iterator), TimeStart) # load subject params SP = cf.sub_params(sub) if 'EOI' in picks and SP['ChInfo'][f"{picks}-{band['name']}"] == []: continue # colect data samples, values = get_samples(sub, band, EpochsSetups, split=split, picks=picks, paired=paired, avg=True) # perform tests pValues = [] # ---- 2 sample test -------- if len(samples[0]) == 2: for s1, s2 in samples: # s1 = [n_observations (i.e. n_epochs), n_channels] pValues += [ ttest_ind(s1 - PopMean, s2, equal_var=False, alternative=alternative)[1] ] # ---- 1 sample test -------- if len(samples[0]) == 1: for s1 in samples: pValues += [ ttest_1samp(s1[0], PopMean, axis=0, alternative=alternative)[1] ] pValues = np.array(pValues) # Bonferroni correction if split != None and Bonferroni: pValues *= len(samples) # fdr correction if fdr: pValues = mne.stats.fdr_correction( pValues[:], cfg.alpha)[1].reshape(pValues.shape) RejectedNull = np.sum(pValues < alpha, axis=0) # boolean with True for significant chs SignificantMask = (RejectedNull > 0) # List of significant ch names SignificantList = [ ch for j, ch in enumerate(cf.get_picks(SP, picks=picks, band=band)) if SignificantMask[j] ] # save to ChInfoFile SP['ChInfo'][f"{EOIlabel}-{band['name']}"] = SignificantList json.dump(SP['ChInfo'], open(SP['ChInfoFile'], 'w')) print( f"\r{sub} {band['name']} {len(SignificantList)}/{len(SignificantMask)} significant channels" ) if figure: ttest_figure_signle_sub(SP, band, EpochsSetups, split, samples, values, SignificantMask, SignificantList, PopMean, pValues, picks, alpha) # concatenate for each band if figure and iSub == len(subs) - 1: #ttest_figure_all_subs() # concatenate figures FiguresPath = cf.check_path(['..', 'Figures', 'ttest' + cfg.out]) FigureName = f"ttest-{EOIlabel}_band-{band['name']}.pdf" cf.concatenate_pdfs(FiguresPath, f'sub*temp', FigureName, remove=True)
def contrast(key1, key2, test1, test2, model1, model2, alpha=sp.alpha, subs=sp.subject_list, bands=sp.bands, plot=True, save=True): """ Plot brain maps for variables (p_value, r2, ...) stored in files for each band Parameters ---------- key : str name of the column to extract test : str name of the test/regression that works as a label for files model1, model2 : dict contains mne queries, file tag alpha : float level of significance (leave out p>alpha) subs : list of str list of subjects to include f.e. [sub-01, sub-02] bands : list of dict list of bands to include """ print(f"\nContrast {test1} {model1['tag']} {test2} {model2['tag']}") df1 = cf.load_df(f"{test1}_{model1['tag']}", subs=subs, bands=bands) df2 = cf.load_df(f"{test2}_{model2['tag']}", subs=subs, bands=bands) fig, ax = plt.subplots(len(bands), 1, figsize=(10, 3 * len(bands))) if len(bands) == 1: ax = np.array([ax]) fig.suptitle( fr"{test1} {key1} {model1['tag']} vs {test2} {key3} {model2['tag']}, $p \leq {alpha}$", fontsize=20) for i_band, band in enumerate(bands): df1_band = df1[df1['band'] == band['name']] df2_band = df2[df2['band'] == band['name']] mask1 = df1_band[key].values < alpha mask2 = df2_band[key].values < alpha # for regression results filter significant channels if test == 'reg': mask1 *= (df1_band['r2'].values > 0) * (df1_band['p'].values < alpha) mask2 *= (df2_band['r2'].values > 0) * (df2_band['p'].values < alpha) x = 1. * mask1 + 2 * mask2 cb = '' if i_band == len(bands) - 1: cb = [model1['tag'], model2['tag'], 'both'] pl.brain_plot(ax[i_band], cf.eval_coords(df1_band['coords']), x, ylabel=band['name'], mask=(x < 0.5), mode='contrast', colorbar=cb) #fig.subplots_adjust(left=0.05, bottom=0.05, right=0.9, top=0.9, wspace=0.3, hspace=0.3) # save figure if save: fig_name = os.path.join( cf.check_path(['..', 'Figures', test1 + sp.out]), f"contrast_{test1}-{model1['tag']}_{test2}-{model2['tag']}.pdf") fig.savefig(fig_name, format='pdf', dpi=100) if plot: plt.show() else: plt.close()
def band_comparison_brain(key, test, file_tag, split=None, alpha=sp.alpha, subs=sp.subject_list, bands=sp.bands): """ Plot brain maps for variables (p_value, r2, ...) stored in files for each band Parameters ---------- key : str name of the column to extract test : str name of the test/regression that works as a label for files queries : dict generated with cf.compose_queries, contains mne queries, file tag, queries list split : int or str if int divide the time window into 'split' chunks and run one test in each if string separate epochs by values of metadata column 'split', f.ex. split = 'w_position' run the test for each word position alpha : float level of significance (leave out p>alpha) subs : list of str list of subjects to include f.e. [sub-01, sub-02] bands : list of dict list of bands to include """ print(f"\nBand comparison brain map for {test} {file_tag}") df = cf.load_df(f"{test}-{file_tag}", subs=subs, bands=bands) if split == None: labels = [''] # no split elif isinstance(split, int): labels = list(np.unique(df['tw'].to_numpy())) # split by time windows elif isinstance(split, str): labels = list(np.unique(df[split].to_numpy())) # split by conditions num_plots = len(labels) # threshold is given in units of p, has to be transformed if key[0] == 'p': alpha = -np.log10(alpha) if len(sp.bands) == 1: ax = ax[np.newaxis, :] # loop over plots for i_plot, label in enumerate(labels): fig, ax = plt.subplots(len(bands), 1, figsize=(10, 3 * len(bands))) fig.suptitle(fr"{test} {file_tag}, $p \leq {alpha}$", fontsize=20) for i_band, band in enumerate(bands): # filter df by band and split if split == None: df_band = df[df['band'] == band['name']] title = '' figtag = '' elif isinstance(split, int): df_band = df[(df['band'] == band['name']) & ([x == label for x in df['tw'].to_numpy()])] title = '' + (str(label) + ' s') * (i_band == 0) figtag = f'_tw{i_plot}' elif isinstance(split, str): df_band = df[(df['band'] == band['name']) & (df[split] == label)] title = '' + f"{split} = {label}" * (i_band == 0) figtag = f"_{split}-{label}" # extract data to plot x = df_band[key] # for p values if key[0] == 'p': # transform p values and threshold x = -np.log10(x) cbar_label = r'-log$_{10}(p)$' # get channel positions coords = np.array([c for c in df_band['coords']]) pl.brain_plot(ax[i_band], coords, np.clip(x, alpha, 3), title=title, ylabel=band['name'], colorbar='' + (i_band == (len(bands) - 1)) * cbar_label, mask=(x < alpha), mode='interval', interval=[alpha, 3]) #fig.subplots_adjust(left=0.05, bottom=0.05, right=0.9, top=0.9, wspace=0.3, hspace=0.3) # save figure fig_name = os.path.join( cf.check_path(['..', 'Figures', test + sp.out]), f"brain_map_{test}_{file_tag}{figtag}.pdf") fig.savefig(fig_name, format='pdf', dpi=100) if sp.plot: plt.show() plt.close()
def channel_overview(sub, ChName, bands, EpochsSetups, EpochsList=None, key=None, plot = True, save = False, temp=False): """ Same as subject overview but for one single channel Parameters ---------- key : str metadata key to plot separate traces by metadata value """ # load subject params SP = cf.sub_params(sub) #if ChName not in SP['ChNames']: sys.exit(f"{sub} {ChName} not found (o_0) ") # make figure fig, ax = plt.subplots(3,len(EpochsSetups),figsize=(5*len(EpochsSetups),4.5)) # add extra dimension if missing if len(EpochsSetups) == 1: ax = np.array([ax]).T title = f"{sub} {ChName}" if 'sample' in EpochsSetups[0].keys(): title += f"\nsample: {EpochsSetups[0]['sample']}" fig.suptitle(title) # plot channel cosition pl.channel_position_plot(ax[0,0],cf.get_coords(SP,picks=[ChName])) pl.clear_axes(ax[0,:]) # LOOP OVER BANDS AND EPOCH SETUPS ----------------------------------------- iterator = product(enumerate(bands),enumerate(EpochsSetups)) for i, ((iBand, band),(iEp, EpochsSetup)) in enumerate(iterator): if EpochsList == None: epochs = cf.load_epochs(sub,band,EpochsSetup) else: epochs = EpochsList[iEp].copy() epochs = epochs.pick_channels([ChName]) xticks = [x*SP['soa'] for x in EpochsSetup['xticks']] # avg PLOT ----------------------------------------------------------- if band['method'] in [None,'filter']: ylabel = f"{band['name']} band\n"*(iEp==0) + f"\nV (z-scored)" elif band['method'] in ['complex']: ylabel = f"{band['name']} band\n"*(iEp==0) + f"\nITC" else: ylabel = f"{band['name']} power\n"*(iEp==0) + f"\ndB (z-scored)" # OPTION 1: plot all epochs together ---------------------------------- if key == None: x = np.squeeze(epochs.get_data(picks=ChName)) # plot avg trace pl.trace_plot(ax[2,iEp], epochs.times, x, ylabel = ylabel, vlines = [SP['soa']*x for x in EpochsSetup['xticks']], plot_sem = True) # OPTION 2: separate epochs by condition ------------------------------- else: conditions=list(set(epochs.metadata[key])) conditions.sort() if isinstance(conditions[0],str): queries = [f"{key} =='{c}'" for c in conditions] elif len(conditions)>10: conditions = np.linspace(min(conditions),max(conditions),5) queries = [f"{key} >={conditions[i]} and {key} <{conditions[i+1]}" for i in range(len(conditions)-1)] else: queries = [f"{key} =={c}" for c in conditions] colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(conditions))) for i_q, query in enumerate(queries): x = np.squeeze(epochs.copy()[query].get_data(picks=ChName)) # plot avg trace per condition pl.trace_plot(ax[2,iEp], epochs.times, x, ylabel = '' + band['name']*(iEp==0), vlines = xticks, plot_sem = True, color=colors[i_q],label = conditions[i_q]) # make legend if iEp==len(EpochsSetups)-1 and key!=None: ax[-1,-1].legend(frameon=False,title=key,loc=(1,0.2),fontsize = 7) # # TrialWise PLOT ----------------------------------------------------------- if band['method'] in [None,'filter']: ylabel, cb = f"{band['name']} band", f"V (z-scored)" elif band['method'] in ['complex']: ylabel, cb =f"{band['name']} band", r"$\theta$" else: ylabel, cb = f"{band['name']} power", f"dB (z-scored)" try: order = EpochsSetup['order'] except: order = key if order!=None: values = epochs.metadata[order].values idx =np.argsort(values) yticks = [j for j, x in enumerate(np.diff(values[idx])!=0) if x] yticklabels = [str(values[idx][y]) for y in yticks] ylabel=(iEp==0)*ylabel + f"\n\n{order}" else: idx = [] yticks = [] yticklabels = [] ylabel=(iEp==0)*ylabel + f"\n\nepoch" m = np.squeeze(epochs.copy().get_data(picks=ChName)) if isinstance(m[0,0],complex): m = np.angle(m) vmin, vmax = -np.pi, np.pi else: m = (m-m.mean())/m.std() vmin = np.percentile(m,15) vmax = np.percentile(m,85) pl.imshow_plot(ax[1,iEp], m,vmin=vmin,vmax=vmax, ylabel = ylabel, xlims = epochs.times, title = EpochsSetup['name'], yticks = yticks, yticklabels = yticklabels, vlines = xticks, colorbar = cb,cmap='jet',order=idx) ax[-1,0].set_xlabel('t (s)') fig.subplots_adjust(wspace=0.3, hspace=0.3) if save: FiguresPath = cf.check_path(['..','Figures' , 'overview' + cfg.out ]) fig_name = os.path.join(FiguresPath,f"{sub}_{ChName}{'_temp'*temp}.pdf") fig.savefig(fig_name, format='pdf') if plot: plt.show() else: plt.close()
def metadata_overview(features, query=None, subs=cfg.subs, key=None, plot_subs = True, plot = True, save = True): print("\n======== metadata overview ========================================\n") # colect metadata metadata_list = [] for sub in cfg.subs: SP = cf.sub_params(sub) sub_metadata = pd.read_csv(SP['metadata_file']) if query!=None: sub_metadata=sub_metadata.query(query) metadata_list += [sub_metadata] # make figure fig, ax = plt.subplots(1+len(subs)*plot_subs,len(features),figsize=(2*len(features),2*(1+len(subs)*plot_subs))) # add extra dimension if missing if not plot_subs: ax = np.array([ax]) fig.suptitle(f"Metadata") metadata_list = [pd.concat(metadata_list)] + metadata_list*plot_subs labels = ['All subjects'] + subs*plot_subs iterator = product(enumerate(metadata_list),enumerate(features)) for (i_m, metadata),(i_f, feature) in iterator: # OPTION 1: plot all epochs together if key == None: # plot all subs together data = metadata[feature].values x = np.arange(data.min()-1.5,data.max()+2) h, _ = np.histogram(data,x,density=True) pl.trace_plot(ax[i_m,i_f], x[:-1]+0.5, h, ylabel = '' + labels[i_m]*(i_f==0), title = '' + feature*(i_m==len(metadata_list)-1)) ax[i_m,i_f].set_xticks(np.arange(data.min(),data.max()+2)) # OPTION 2: separate epochs by condition else: conditions=list(set(metadata[key])) conditions.sort() queries = [f"{key} =='{c}'" for c in conditions] colors = plt.get_cmap('viridis')(np.linspace(0, 1, len(conditions))) for i_q, query in enumerate(queries): data = metadata[feature].values x = np.arange(data.min()-1.5,data.max()+2) data_query = metadata.query(query)[feature].values h, _ = np.histogram(data_query,x,density=True) pl.trace_plot(ax[i_m,i_f], x[:-1]+0.5, h, ylabel = '' + labels[i_m]*(i_f==0), xlabel = '' + feature*(i_m==len(metadata_list)-1) ,color=colors[i_q],label = conditions[i_q]) ax[i_m,i_f].set_xticks(np.arange(data.min(),data.max()+2)) ax[0,-1].legend(frameon=False,loc=(0.5,0.5)) fig.subplots_adjust(top=0.8,bottom=0.2,wspace=0.3, hspace=0.3) if save: FiguresPath =cf.check_path(['..','Figures' , 'overview'+ cfg.out]) fig_name = os.path.join(FiguresPath,f"metadata.pdf") fig.savefig(fig_name, format='pdf') if plot: plt.show() else: plt.close()
def reg_single_channel(sub, ch_name, band, model, alpha=cfg.alpha, plot=True, save=True, temp=True, n=4): # load subject params dp = cf.sub_params(sub) # load epochs all_epochs = cf.load_epochs(sub, band, model['ep_setup'], picks=[ch_name]).decimate(5) epochs = all_epochs[model['query']] # regression scores, ps = stepwise_regression(epochs, model['predictors'], model['predictors_stepwise']) predictors = model['predictors_stepwise'] # FIGURE -------------------------------------------------------- fig, ax = plt.subplots(len(predictors) + 1, 3, figsize=(15, 3 * (len(predictors) + 1))) fig.suptitle(f"{sub} {ch_name} {band['name']}\n{model['query']}", fontsize=15) # ch_position pl.channel_position_plot(ax[0, 2], cf.get_coords(epochs, picks=[ch_name])) # channel summary pl.channel_summary_plot(ax[0, 1], sub, ch_name, model['tag'], model['predictors']) t_sig = pl.score_plot( ax[0, 0], scores, ps, epochs.times, model['predictors_stepwise'], vlines=[dp['soa'] * x for x in model['ep_setup']['xticks']], xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']]) ax[1, 0].set_title(model['query']) if np.sum(np.array([len(t_sig[pr]) == 2 for pr in predictors])) == 0: plt.close() return for i_p, predictor in enumerate(predictors): predictor_values = epochs.metadata[predictor].values N = min(n, len(set(predictor_values))) predictor_thresholds = np.linspace(np.nanmin(predictor_values), np.nanmax(predictor_values), N + 1) #predictor_thresholds = np.percentile(predictor_values, np.linspace(0,100,N+1)) colors = plt.get_cmap('autumn')(np.linspace(0., 1., N)) for i in range(N): y = np.squeeze(epochs[ f'{predictor}>={predictor_thresholds[i]} and {predictor}<={predictor_thresholds[i+1]}'] .get_data(picks=ch_name)) label = f"({round(predictor_thresholds[i])},{round(predictor_thresholds[i+1])})" pl.trace_plot( ax[i_p + 1, 0], epochs.times, y, ylabel='zscored power', title=predictor, xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']], vlines=[dp['soa'] * x for x in model['ep_setup']['xticks']], color=colors[i], label=label, legend=True, plot_sem=True, xlabel='t (s)') if len(t_sig[predictor]) == 2: ax[i_p + 1, 0].axvspan(t_sig[predictor][0] - cfg.smooth * 0.5, t_sig[predictor][1] + cfg.smooth * 0.5, color='gray', alpha=0.3, lw=0) pl.response_plot(ax[i_p + 1, 1], ch_name, all_epochs.copy(), predictor, tmin=t_sig[predictor][0] - cfg.smooth * 0.5, tmax=t_sig[predictor][1] + cfg.smooth * 0.5) else: pl.clear_axes(np.array([ax[i_p + 1, 1]])) values = all_epochs.metadata[predictor].values order = np.argsort(values) yticks = [j for j, x in enumerate(np.diff(values[order]) != 0) if x] yticklabels = [str(values[order][idx]) for idx in yticks] m = np.squeeze(all_epochs.copy().get_data(picks=ch_name)) m = (m - m.mean()) / m.std() vmin = np.percentile(m, 15) vmax = np.percentile(m, 85) pl.imshow_plot(ax[i_p + 1, 2], m, vmin=vmin, vmax=vmax, ylabel=predictor, xlims=all_epochs.times, yticks=yticks, yticklabels=yticklabels, colorbar='z-score', cmap='RdBu_r', order=order) fig.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=0.3, hspace=0.4) if save: fig_name = os.path.join( cf.check_path(['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]), f"{sub}_{ch_name}_{band['name']}_temp.pdf") fig.savefig(fig_name, format='pdf', dpi=100) if plot: plt.show() else: plt.close()
def band_comparison_lateralization(key, test, tag, split=None, alpha=sp.alpha, subs=sp.subject_list, bands=sp.bands): """ Bar plots for proportion of significant channels on left right axis and frontal occipital axis Parameters ---------- key : str name of the column to extract test : str name of the test/regression that works as a label for files tag : str test tag alpha : float level of significance (leave out p>alpha) subs : list of str list of subjects to include f.e. [sub-01, sub-02] bands : list of dict list of bands to include """ print(f"\nLateralization figure for {test} {tag}") df = cf.load_df(f"{test}_{tag}", subs=subs, bands=bands) if split == None: labels = [''] # no split elif isinstance(split, int): labels = list(np.unique(df['tw'].to_numpy())) # split by time windows elif isinstance(split, str): labels = list(np.unique(df[split].to_numpy())) # split by conditions num_plots = len(labels) if len(sp.bands) == 1: ax = ax[np.newaxis, :] # loop over plots for i_plot, label in enumerate(labels): fig, ax = plt.subplots(len(bands), 2, figsize=(5, 3 * len(bands))) fig.suptitle(fr"{test} {tag}, $p \leq {alpha}$", fontsize=20) # for axis limits x, y = 0, 0 for i_band, band in enumerate(bands): # filter df by band and split if split == None: df_band = df[df['band'] == band['name']] title = '' figtag = '' elif isinstance(split, int): df_band = df[(df['band'] == band['name']) & ([x == label for x in df['tw'].to_numpy()])] title = '' + (str(label) + ' s') * (i_band == 0) figtag = f'_tw{i_plot}' elif isinstance(split, str): df_band = df[(df['band'] == band['name']) & (df[split] == label)] title = '' + f"{split} = {label}" * (i_band == 0) figtag = f"_{split}-{label}" df_sig = df_band[df_band[key] <= alpha] # get channel positions coords_all = np.array([c for c in df_band['coords']]) coords_sig = np.array([c for c in df_sig['coords']]) # skip if there aren't significant channels if len(coords_sig.shape) != 2: continue # left rigth h_all, bins = np.histogram(coords_all[:, 0], bins=6, density=False) h_sig, bins = np.histogram(coords_sig[:, 0], bins=bins, density=False) width = (bins[1] - bins[0]) ax[i_band, 0].bar(bins[:-1] + width / 2, h_sig / h_all, width=width * 0.9, color='firebrick') ax[i_band, 0].set_xticks([bins[0], bins[-1]]) ax[i_band, 0].set_xticklabels(['L', 'R']) #ax[i_band,0].set_ylim([0,1]) ax[i_band, 0].spines['right'].set_visible(False) ax[i_band, 0].spines['top'].set_visible(False) ax[i_band, 0].tick_params(axis='both', which='both', size=0, labelsize=9) y = max(y, np.max(h_sig / h_all)) # frontal occipital h_all, bins = np.histogram(coords_all[:, 1], bins=6, density=False) h_sig, bins = np.histogram(coords_sig[:, 1], bins=bins, density=False) width = (bins[1] - bins[0]) ax[i_band, 1].barh(bins[:-1] + width / 2, h_sig / h_all, height=width * 0.9, color='firebrick') ax[i_band, 1].set_yticks([bins[0], bins[-1]]) ax[i_band, 1].set_yticklabels(['O', 'F']) #ax[i_band,1].set_xlim([0,1]) ax[i_band, 1].spines['right'].set_visible(False) ax[i_band, 1].spines['top'].set_visible(False) ax[i_band, 1].tick_params(axis='both', which='both', size=0, labelsize=9) x = max(x, np.max(h_sig / h_all)) for i_band in range(len(bands)): ax[i_band, 0].set_ylim([0, y]) ax[i_band, 1].set_xlim([0, x]) fig.subplots_adjust(left=0.1, bottom=0.15, right=0.95, top=0.85, wspace=0.4, hspace=0.4) # save figure fig_name = os.path.join( cf.check_path(['..', 'Figures', f"{test}_{tag}" + sp.out]), f"lateralization_{test}_{tag}_{key}.pdf") fig.savefig(fig_name, format='pdf', dpi=100) if sp.plot: plt.show() plt.close()
def reg_single_channel2(sub, ch_name, band_name, model, extra_band, predictor2, predictors='all', alpha=cfg.alpha, plot=True, save=False, temp=False, n=4, twsize=cfg.tws): # load subject params dp = cf.sub_params(sub) if predictors == 'all': predictors = model['predictors'] ep_setup = model['ep_setup'] # raw file mneraw_file = os.path.join(dp['derivatives_path'], f"{sub}_band-{band_name}_raw.fif") raw = mne.io.read_raw_fif(mneraw_file, preload=True) all_epochs = cf.load_epochs(dp, raw.copy().pick_channels([ch_name]), model['ep_setup']) epochs = all_epochs[model['query']] # get predictor values X = np.array(epochs.metadata[model['predictors']]) X[np.isinf(X)] = -15.5 # get responses averaged over time windows tmin, tmax = model['ep_setup']['tmin'], model['ep_setup']['tmax'] - twsize tws = [[t, t + cfg.tws] for t in np.arange(tmin, tmax, (tmax - tmin) / 100.)] y = [] t = [] for t1, t2 in tws: # epoch average e = epochs.copy() y += [np.squeeze(e.crop(t1, t2).get_data(picks=ch_name).mean(axis=-1))] t += [0.5 * (t1 + t2)] y = np.swapaxes(np.array([y]).T, -1, -2) # compute regressions R = regression(X, y, t) # FIGURE -------------------------------------------------------- fig, ax = plt.subplots(len(predictors) + 2, 3, figsize=(15, 3 * (len(predictors) + 2))) fig.suptitle( f"{sub} {ch_name} {band_name}\n{model['predictors']}\n{model['query']}", fontsize=15) # ch_position #pl.clear_axes(ax[0,:]) pl.channel_position_plot(ax[0, 0], [dp['coords'][dp['ch_names'].index(ch_name)]], 0) # channel summary pl.channel_summary_plot(ax[0, 1], sub, ch_name, model['tag'], model['predictors']) # raster plot y = cf.load_epochs(dp, raw.copy().pick_channels([ch_name]), model['ep_setup']).get_data(picks=ch_name) #y = (y - np.median(y))/np.subtract(*np.percentile(y, [75, 25])) y = (y - np.median(y)) / y.std() pl.imshow_plot( ax[1, 1], y[:, 0, :], title='All trials', xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']], vlines=[dp['soa'] * x for x in ep_setup['xticks']], ylabel='epoch', colorbar='zscore', vmin=-1, vmax=1, cmap='RdBu_r') # score plot t_sig = pl.score_plot( ax[1, 0], R, model['predictors'], vlines=[dp['soa'] * x for x in ep_setup['xticks']], xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']]) ax[1, 0].set_title(model['query']) if np.sum(np.array([len(t_sig[pr]) == 2 for pr in predictors])) == 0: plt.close() return for i_p, predictor in enumerate(predictors): predictor_values = epochs.metadata[predictor].values predictor_values[np.isinf(predictor_values)] = -15.5 N = min(n, len(set(predictor_values))) predictor_thresholds = np.linspace(np.nanmin(predictor_values), np.nanmax(predictor_values), N + 1) colors = plt.get_cmap('autumn')(np.linspace(0., 1., N)) for i in range(N): y = np.squeeze(epochs[ f'{predictor}>={predictor_thresholds[i]} and {predictor}<={predictor_thresholds[i+1]}'] .get_data(picks=ch_name)) label = f"({round(predictor_thresholds[i])},{round(predictor_thresholds[i+1])})" pl.trace_plot( ax[i_p + 2, 0], epochs.times, y, ylabel='zscored power', title=predictor, xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']], vlines=[dp['soa'] * x for x in ep_setup['xticks']], color=colors[i], label=label, legend=True, plot_sem=True, xlabel='t (s)') if len(t_sig[predictor]) == 2: ax[i_p + 2, 0].axvspan(t_sig[predictor][0], t_sig[predictor][1], color='gray', alpha=0.3, lw=0) pl.response_plot(ax[i_p + 2, 1], ch_name, all_epochs.copy(), predictor, tmin=t_sig[predictor][0], tmax=t_sig[predictor][1]) else: pl.clear_axes(np.array([ax[i_p + 2, 1]])) # Third column order = np.argsort( np.squeeze(epochs.copy().crop( t_sig[predictor2][0], t_sig[predictor2][1]).get_data(picks=ch_name).mean(axis=-1))) # raster plot y = epochs.get_data(picks=ch_name) y = (y - np.median(y)) / y.std() pl.imshow_plot( ax[1, 2], y[order, 0, :], title=f"{band_name} {predictor2} ordered", xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']], vlines=[dp['soa'] * x for x in ep_setup['xticks']], ylabel='epoch', colorbar='zscore', vmin=-1, vmax=1, cmap='RdBu_r') for i in range(len(extra_band)): # raw file mneraw_file = os.path.join(dp['derivatives_path'], f"{sub}_band-{extra_band[i]}_raw.fif") raw = mne.io.read_raw_fif(mneraw_file, preload=True) all_epochs = cf.load_epochs(dp, raw.copy().pick_channels([ch_name]), model['ep_setup']) epochs = all_epochs[model['query']] # raster plot y = epochs.get_data(picks=ch_name) y = (y - np.median(y)) / y.std() pl.imshow_plot( ax[2 + i, 2], y[order, 0, :], title=f"{extra_band[i]}", xlims=[model['ep_setup']['tmin'], model['ep_setup']['tmax']], vlines=[dp['soa'] * x for x in ep_setup['xticks']], ylabel='epoch', colorbar='zscore', vmin=-1, vmax=1, cmap='RdBu_r') pl.clear_axes(np.array(ax[0, 2])) fig.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=0.3, hspace=0.4) if save: #i_band = [band['name'] for band in cfg.bands].index(band_name) fig_name = os.path.join( cf.check_path(['..', 'Figures' + cfg.out, f"reg_{model['tag']}"]), f"{sub}_{ch_name}_{band_name}_temp.pdf") fig.savefig(fig_name, format='pdf', dpi=100) if plot: plt.show() else: plt.close()
def ttest_figure_signle_sub(SP, band, EpochsSetups, split, samples, values, SignificantMask, SignificantList, PopMean, pValues, picks, alpha): # mean and sem across epochs # ---- 2 sample test -------- if len(samples[0]) == 2: m = np.array([[s1.mean(axis=0), s2.mean(axis=0)] for s1, s2 in samples]) s = np.array([[ s1.std(axis=0) / np.sqrt(len(s1)), s2.std(axis=0) / np.sqrt(len(s2)) ] for s1, s2 in samples]) x = m[:, 0] - m[:, 1] xerr = np.sqrt(0.5) * (s[:, 0] + s[:, 1]) # ---- 1 sample test -------- if len(samples[0]) == 1: x = np.array([s1[0].mean(axis=0) for s1 in samples]) xerr = np.array( [s1[0].std(axis=0) / np.sqrt(len(s1[0])) for s1 in samples]) # ---- Make Figure ---------------- fig, ax = plt.subplots(2, 1, figsize=(5, 12), gridspec_kw={'height_ratios': [1, 5]}) title = f"T-test {SP['sub']} {band['name']} ({np.sum(SignificantMask)}/{len(SignificantMask)})" if 'sample' in EpochsSetups[0].keys(): title += f"\nsample: {EpochsSetups[0]['sample']}" fig.suptitle(title) # ---- plot glass brain ------------ coords = np.array([ SP['ChInfo']['coords'][SP['ChInfo']['ChNames'].index(ch)] for ch in cf.get_picks(SP, picks=picks, band=band) ]) pl.channel_position_plot(ax[0], coords, mask=~SignificantMask) # ---- scatter plot with mean and std ------ y = np.arange(len(SignificantMask)) if split == None: ax[1].errorbar(x[0], y, xerr=xerr[0], color='k', fmt='o', alpha=0.1) ax[1].errorbar(x[0, SignificantMask], y[SignificantMask], xerr=xerr[0, SignificantMask], color='k', fmt='o') else: colors = plt.get_cmap('turbo')(np.linspace(0., 1., len(values))) for j, v in enumerate(values): mask = pValues[j] < alpha ax[1].errorbar(x[j], y, xerr=xerr[j], color=colors[j], fmt='o', alpha=0.1) ax[1].errorbar(x[j, mask], y[mask], xerr=xerr[j, mask], color=colors[j], fmt='o', label=f"{v}") if isinstance(split, list): title = 'time window' else: title = split ax[1].legend(title=title, frameon=False) # ---- decorate axes ------------ ax[1].set_xlabel( f"{EpochsSetups[0]['name']} - {EpochsSetups[1]['name']} dB") ax[1].set_ylabel('channel') ax[1].set_yticks( [j for j in range(len(SignificantMask)) if SignificantMask[j]]) ax[1].set_yticklabels(SignificantList) ax[1].axvline(PopMean, linestyle='-', color='grey', linewidth=0.5) ax[1].spines['right'].set_visible(False) ax[1].spines['top'].set_visible(False) ax[1].tick_params(axis='both', which='both', size=0, labelsize=7) # ---- save figure -------------- FiguresPath = cf.check_path(['..', 'Figures', 'ttest' + cfg.out]) FigureName = os.path.join(FiguresPath, f"{SP['sub']}_{band['name']}_temp.pdf") fig.savefig(FigureName, format='pdf', dpi=100) plt.close()