% Create an overview plot featuring the results of the multivariate PLS % comparing spectral changes during the stimulus period under load clear all; cla; clc; currentFile = mfilename('fullpath'); [pathstr,~,~] = fileparts(currentFile); cd(fullfile(pathstr,'..')) rootpath = pwd; pn.data = fullfile(rootpath, 'data', 'stats'); pn.figures = fullfile(rootpath, 'figures'); pn.tools = fullfile(rootpath, 'tools'); addpath(genpath(fullfile(pn.tools, '[MEG]PLS', 'MEGPLS_PIPELINE_v2.02b'))) addpath(fullfile(pn.tools, 'fieldtrip')); ft_defaults; addpath(genpath(fullfile(pn.tools, 'RainCloudPlots'))); addpath(fullfile(pn.tools, 'BrewerMap')); addpath(fullfile(pn.tools, 'winsor')); % set custom colormap cBrew = brewermap(500,'RdBu'); cBrew = flipud(cBrew); colormap(cBrew) load(fullfile(pn.data, 'd1_taskpls_erp.mat'),... 'stat', 'result', 'lvdat', 'lv_evt_list', 'num_chans', 'num_freqs', 'num_time') load(fullfile(rootpath, 'data','erp', ['sub-001_erp.mat'])); elec = erp.scene_category{1}.elec; result.perm_result.sprob indLV = 1; lvdat = reshape(result.boot_result.compare_u(:,indLV), num_chans, num_freqs, num_time); stat.prob = lvdat; stat.mask = lvdat > 3 | lvdat < -3; % maskNaN = double(stat.mask); % maskNaN(maskNaN==0) = NaN; %% invert solution stat.mask = stat.mask; stat.prob = stat.prob.*-1; result.vsc = result.vsc.*-1; result.usc = result.usc.*-1; %% plot temporal loadings h = figure('units','centimeter','position',[0 0 10 10]); set(gcf,'renderer','Painters') hold on; % highlight relevant phase in background patches.timeVec = [.35 .55]; patches.colorVec = [.8 .95 1]; for indP = 1:size(patches.timeVec,2)-1 YLim = [-.5 .5]; p = patch([patches.timeVec(indP) patches.timeVec(indP+1) patches.timeVec(indP+1) patches.timeVec(indP)], ... [YLim(1) YLim(1) YLim(2), YLim(2)], patches.colorVec(indP,:)); p.EdgeColor = 'none'; end % highlight relevant phase in background patches.timeVec = [.6 1]; patches.colorVec = [1 .95 .8]; for indP = 1:size(patches.timeVec,2)-1 YLim = [-.5 .5]; p = patch([patches.timeVec(indP) patches.timeVec(indP+1) patches.timeVec(indP+1) patches.timeVec(indP)], ... [YLim(1) YLim(1) YLim(2), YLim(2)], patches.colorVec(indP,:)); p.EdgeColor = 'none'; end % highlight relevant phase in background patches.timeVec = [1.2 1.7]; patches.colorVec = [1 .8 .7]; for indP = 1:size(patches.timeVec,2)-1 YLim = [-.5 .5]; p = patch([patches.timeVec(indP) patches.timeVec(indP+1) patches.timeVec(indP+1) patches.timeVec(indP)], ... [YLim(1) YLim(1) YLim(2), YLim(2)], patches.colorVec(indP,:)); p.EdgeColor = 'none'; end statsPlot = []; statsPlot = cat(1, statsPlot,squeeze(nanmean(stat.mask(1:64,:,:).*stat.prob(1:64,:,:),1))); plot(stat.time,statsPlot, 'k') xlabel('Time [s from stim onset]'); ylabel('mean BSR'); title({'ERP changes'; ['p = ', num2str(round(result.perm_result.sprob(indLV),4))]}) set(findall(gcf,'-property','FontSize'),'FontSize',18) figureName = ['d1_rec_erp_bsr']; saveas(h, fullfile(pn.figures, figureName), 'epsc'); saveas(h, fullfile(pn.figures, figureName), 'png'); %% plot early positivity/negativity h = figure('units','centimeters','position',[0 0 10 10]); set(gcf,'renderer','Painters') cfg = []; cfg.layout = 'biosemi64.lay'; cfg.parameter = 'powspctrm'; cfg.comment = 'no'; cfg.colormap = cBrew; cfg.colorbar = 'EastOutside'; plotData = []; plotData.label = elec.label; % {1 x N} plotData.dimord = 'chan'; cfg.zlim = [-4 4]; cfg.figure = h; plotData.powspctrm = squeeze(nanmean(stat.mask(:,:,stat.time>.35 & stat.time<.55).*... stat.prob(:,:,stat.time>.35 & stat.time<.55),3)); [~, sortind] = sort(plotData.powspctrm, 'ascend'); cfg.marker = 'off'; cfg.highlight = 'yes'; cfg.highlightchannel = plotData.label(sortind([1:2, end])); % 42, 35 (neg) 37 (pos) cfg.highlightcolor = [0 0 0]; cfg.highlightsymbol = '.'; cfg.highlightsize = 30; ft_topoplotER(cfg,plotData); cb = colorbar('location', 'EastOutside'); set(get(cb,'ylabel'),'string','Mean BSR'); figureName = ['d1_rec_erp_topo1']; saveas(h, fullfile(pn.figures, figureName), 'epsc'); saveas(h, fullfile(pn.figures, figureName), 'png'); %% plot later positivity h = figure('units','centimeters','position',[0 0 10 10]); set(gcf,'renderer','Painters') cfg = []; cfg.layout = 'biosemi64.lay'; cfg.parameter = 'powspctrm'; cfg.comment = 'no'; cfg.colormap = cBrew; cfg.colorbar = 'EastOutside'; plotData = []; plotData.label = elec.label; % {1 x N} plotData.dimord = 'chan'; cfg.zlim = [-4 4]; cfg.figure = h; plotData.powspctrm = squeeze(nanmean(stat.mask(:,:,stat.time>.6 & stat.time<1).*... stat.prob(:,:,stat.time>0.6 & stat.time<1),3)); [~, sortind] = sort(plotData.powspctrm, 'descend'); cfg.marker = 'off'; cfg.highlight = 'yes'; cfg.highlightchannel = plotData.label(sortind([1:2])); % 19, 21 cfg.highlightcolor = [0 0 0]; cfg.highlightsymbol = '.'; cfg.highlightsize = 30; ft_topoplotER(cfg,plotData); cb = colorbar('location', 'EastOutside'); set(get(cb,'ylabel'),'string','Mean BSR'); figureName = ['d1_rec_erp_topo2']; saveas(h, fullfile(pn.figures, figureName), 'epsc'); saveas(h, fullfile(pn.figures, figureName), 'png'); %% plot late negativity h = figure('units','centimeters','position',[0 0 10 10]); set(gcf,'renderer','Painters') cfg = []; cfg.layout = 'biosemi64.lay'; cfg.parameter = 'powspctrm'; cfg.comment = 'no'; cfg.colormap = cBrew; cfg.colorbar = 'EastOutside'; plotData = []; plotData.label = elec.label; % {1 x N} plotData.dimord = 'chan'; cfg.zlim = [-2.5 2.5]; cfg.figure = h; plotData.powspctrm = squeeze(nanmean(stat.mask(:,:,stat.time>1.2 & stat.time<1.7).*... stat.prob(:,:,stat.time>1.2 & stat.time<1.7),3)); [~, sortind] = sort(plotData.powspctrm, 'descend'); cfg.marker = 'off'; cfg.highlight = 'yes'; %cfg.highlightchannel = plotData.label(sortind([end-3:end])); % 63, 26, 21, 58 (negative) %cfg.highlightchannel = plotData.label(sortind([8])); % 16, 53, 15, 54, 52, 51 (positive lateral) %cfg.highlightchannel = plotData.label([16, 53, 15, 52]); % (positive lateral) %cfg.highlightchannel = plotData.label([28]); % (positive posterior) cfg.highlightchannel = plotData.label([63, 26, 21, 58, 16, 53, 15, 52, 28]); % (positive posterior) cfg.highlightcolor = [.5 .5 .5]; cfg.highlightsymbol = '.'; cfg.highlightsize = 30; ft_topoplotER(cfg,plotData); cb = colorbar('location', 'EastOutside'); set(get(cb,'ylabel'),'string','Mean BSR'); figureName = ['d1_rec_erp_topo3']; saveas(h, fullfile(pn.figures, figureName), 'epsc'); saveas(h, fullfile(pn.figures, figureName), 'png'); %% plot using raincloud plot groupsizes=result.num_subj_lst; conditions=lv_evt_list; conds = {'hit'; 'miss'}; condData = []; uData = []; for indGroup = 1 if indGroup == 1 relevantEntries = 1:groupsizes(1)*numel(conds); elseif indGroup == 2 relevantEntries = groupsizes(1)*numel(conds)+1:... groupsizes(1)*numel(conds)+groupsizes(2)*numel(conds); end for indCond = 1:numel(conds) targetEntries = relevantEntries(conditions(relevantEntries)==indCond); condData{indGroup}(indCond,:) = result.vsc(targetEntries,indLV); uData{indGroup}(indCond,:) = result.usc(targetEntries,indLV); end end cBrew(1,:) = 2.*[.3 .1 .1]; cBrew(2,:) = [.6 .6 .6]; idx_outlier = cell(1); idx_standard = cell(1); for indGroup = 1 dataToPlot = uData{indGroup}'; % define outlier as lin. modulation that is more than three scaled median absolute deviations (MAD) away from the median X = [1 1; 1 2]; b=X\dataToPlot'; IndividualSlopes = b(2,:); outliers = isoutlier(IndividualSlopes, 'median'); idx_outlier{indGroup} = find(outliers); idx_standard{indGroup} = find(outliers==0); end h = figure('units','centimeter','position',[0 0 8 10]); ax = subplot(1,1,1); for indGroup = 1 dataToPlot = uData{indGroup}'; % read into cell array of the appropriate dimensions data = []; data_ws = []; for i = 1:2 for j = 1:1 data{i, j} = dataToPlot(:,i); % individually demean for within-subject visualization data_ws{i, j} = dataToPlot(:,i)-... nanmean(dataToPlot(:,:),2)+... repmat(nanmean(nanmean(dataToPlot(:,:),2),1),size(dataToPlot(:,:),1),1); data_nooutlier{i, j} = data{i, j}; data_nooutlier{i, j}(idx_outlier{indGroup}) = []; data_ws_nooutlier{i, j} = data_ws{i, j}; data_ws_nooutlier{i, j}(idx_outlier{indGroup}) = []; % sort outliers to back in original data for improved plot overlap data_ws{i, j} = [data_ws{i, j}(idx_standard{indGroup}); data_ws{i, j}(idx_outlier{indGroup})]; end end % IMPORTANT: plot individually centered estimates, stats on uncentered estimates! %subplot(1,2,indGroup); set(gcf,'renderer','Painters') cla; cl = cBrew(indGroup,:); [~, dist] = rm_raincloud_fixedSpacing(data_ws, [.8 .8 .8],1); h_rc = rm_raincloud_fixedSpacing(data_ws_nooutlier, cl,1,[],[],[],dist); view([90 -90]); axis ij box(gca,'off') set(gca, 'YTickLabels', {conds{2}; conds{1}}); yticks = get(gca, 'ytick'); ylim([yticks(1)-(yticks(2)-yticks(1))./2, yticks(2)+(yticks(2)-yticks(1))./1.5]); minmax = [min(min(cat(2,data_ws{:}))), max(max(cat(2,data_ws{:})))]; xlim(minmax+[-0.2*diff(minmax), 0.2*diff(minmax)]) ylabel('recognition'); xlabel({'Brainscore'; '[Individually centered]'}) % test linear effect curData = [data_nooutlier{1, 1}, data_nooutlier{2, 1}]; X = [1 1; 1 2]; b=X\curData'; IndividualSlopes = b(2,:); [~, p, ci, stats] = ttest(IndividualSlopes); title(['M:', num2str(round(mean(IndividualSlopes),3)), '; p=', num2str(round(p,6))]) end % make misses initial tick ax.XDir = 'reverse'; set(ax, 'YTickLabels', {conds{1}; conds{2}}); figureName = ['d1_rec_erp_rcp']; saveas(h, fullfile(pn.figures, figureName), 'epsc'); saveas(h, fullfile(pn.figures, figureName), 'png');