RS_Plotting.m 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. %% define some variables
  2. filt = 6; % 1: non, 2: 0.1 Hz, 3: 10 Hz, 4: 40 Hz, 5: 45 Hz, 6: 50 Hz
  3. cutTime = 0; % plot only certain time window? (0: no, 1: short, 2: long)
  4. avType = 1; % plot grand average (1) or individual averages (2)
  5. varType = 1; % plot stats of amplitude or timing variable? (1: amplitude, 2: timimg)
  6. repRateI = 1; % which rep rate to plot (1: 25 ms, 2: 50 ms)
  7. fixedY = 0; % use dynamic (0) or fixed (1) y-axis?
  8. plotRespI = 0;
  9. plotRespOsciI = 1; % plot oscillogram of the responses?
  10. plotRespSpecI = 0; % plot spectrogram of the responses?
  11. plotWinI = 1; % plot stat windows?
  12. plotSeI = 0; % plot data with or without Standard error?
  13. win = 1; % stats window to be plotted (it's always 2 if varType is 2)
  14. plotCurveI = 1; % plot fitted curve?
  15. curveInt = 1; % which interval should be plotted on x? (1: Rep#; 2: time)
  16. saveI = 1; % save figure?
  17. chirpPeak = [0.00648,0.00842];
  18. %% load processed data
  19. switch repRateI
  20. case 1
  21. load('RS_avData_25ms.mat') % load preprocessed data
  22. load('RS_statsData_25ms.mat') % load stats data
  23. case 2
  24. load('RS_avData_50ms.mat') % load data
  25. load('RS_statsData_50ms.mat') % load stats data
  26. end
  27. col = 'k';
  28. %% do some additional calculations
  29. % decide which set of rms-windows to plot
  30. if varType==2
  31. win = 2; % always use second window if plotting peak timing
  32. end
  33. uWin = (win:win);
  34. % define y-label name
  35. switch zsNormI
  36. case 0
  37. ylabelName = 'Voltage [µV]';
  38. case 1
  39. ylabelName = 'z-norm. Voltage [a.u.]';
  40. end
  41. % define x-Axis
  42. switch cutTime
  43. case 0
  44. xtickSteps = 100; % ms-steps on x-axis that should be plotted
  45. case 1
  46. xtickSteps = 5; % ms-steps on x-axis that should be plotted
  47. switch filt
  48. case {1,2,3}
  49. timeStart = 0; % starting time of the plot (relative to stim onset)
  50. timeEnd = 20; % ending time of the plot (relative to stim onset)
  51. case {4,5}
  52. timeStart = 0; % starting time of the plot (relative to stim onset)
  53. timeEnd = 20; % ending time of the plot (relative to stim onset)
  54. end
  55. case 2
  56. xtickSteps = 50; % ms-steps on x-axis that should be plotted
  57. timeStart = 0; % starting time of the plot (relative to stim onset)
  58. switch repRateI
  59. case 1
  60. timeEnd = 350; % ending time of the plot (relative to stim onset)
  61. case 2
  62. timeEnd = 450; % ending time of the plot (relative to stim onset)
  63. end
  64. end
  65. % define some names
  66. combNameS = split(combName,","); % split comb names at comma
  67. if filt==1
  68. filtName = 'noF';
  69. else
  70. filtName = num2str(lowc(filt-1));
  71. end
  72. % define y-axis depending on filter setting and plotted time frame
  73. switch filt
  74. case 1
  75. switch cutTime
  76. case 0
  77. y_lim = [-0.8,1];
  78. case 1
  79. y_lim = [-0.8,1];
  80. case 2
  81. y_lim = [-0.8,1];
  82. end
  83. case 2
  84. switch cutTime
  85. case 0
  86. y_lim = [-3,2];
  87. case 1
  88. y_lim = [-3,2];
  89. case 2
  90. y_lim = [-3,2];
  91. end
  92. case 3
  93. switch cutTime
  94. case 0
  95. y_lim = [-0.9,1];
  96. case 1
  97. y_lim = [-0.3,0.55];
  98. case 2
  99. y_lim = [-0.9,1];
  100. end
  101. case 4
  102. switch cutTime
  103. case 0
  104. y_lim = [-0.3,0.7];
  105. case 1
  106. y_lim = [-0.3,0.7];
  107. case 2
  108. y_lim = [-0.3,0.7];
  109. end
  110. case 5
  111. switch cutTime
  112. case 0
  113. y_lim = [-0.3,0.7];
  114. case 1
  115. y_lim = [-0.3,0.7];
  116. case 2
  117. y_lim = [-0.3,0.7];
  118. end
  119. case 6
  120. switch cutTime
  121. case 0
  122. y_lim = [-0.3,0.7];
  123. case 1
  124. y_lim = [-0.3,0.7];
  125. case 2
  126. y_lim = [-0.3,0.7];
  127. end
  128. end
  129. % do some prior calculations for colormap
  130. rgb1 = [ones(1,100),ones(1,100),(1:-0.01:0.01)]';
  131. rgb2 = [ones(1,100),(1:-0.01:0.01),zeros(1,100)]';
  132. rgb3 = [(1:-0.01:0.01),zeros(1,100),zeros(1,100)]';
  133. cMap = [rgb1,rgb2,rgb3];
  134. % do some prior calculations for tiled plots
  135. yMax = 1.5; % y-axis maximum in kHz for spectrogram
  136. % change stats variables if timing is selected
  137. if varType==2
  138. varS = timS;
  139. varAvS = timAvS;
  140. varSeS = timSeS;
  141. end
  142. %% plotting: responses
  143. if plotRespI==1
  144. switch avType
  145. case 1
  146. for f = 1:2 % once for each stimulation type (block-stim and o1st-stim)
  147. for s = 1:2 % run once for each stimulus combination
  148. figure('NumberTitle','off','Name',[num2str(f),'_',SOAName,],'Position',[0,0,1500,1300])
  149. set(gca,'FontSize',20,'Linewidth',2,'FontName','Arial')
  150. c = (f-1)*2+s; % index of dataset to be used
  151. nResp = nResp_cell{c};
  152. % extract data corresponding to current stimulation-condition from
  153. % cell-arrays
  154. dataAv = dataAv_cell{c};
  155. dataGrAv = dataGrAv_cell{c};
  156. dataSe = dataSe_cell{c};
  157. filenames = filenames_stim_cell{c};
  158. recID = recID_cell{c};
  159. bsPos = cell2mat(strfind(filenames,'\')); % find positions of back slashes in filename
  160. startPos = bsPos(:,end); % use last back slash position as starting point
  161. filenames = extractAfter(filenames,startPos);
  162. timetr = round(timetrUnit_cell{c}*1000,4);
  163. stimDur = stimDur_cell{c}(1)*1000;
  164. stimDelay = stimDelay_cell{c}(1)*1000;
  165. stimWin = [stimDelay,stimDelay+stimDur];
  166. nFiles = nFiles_cell{c};
  167. fs_stim = fs_stim_cell{c};
  168. fs = fs_cell{c};
  169. stimCat = stimCat_cell{c};
  170. pts2begin = pts2begin_cell{c};
  171. % process timetrace
  172. switch cutTime
  173. case 0
  174. timeWin = floor([timetr(1),timetr(end)]); % data in this window will be plotted (relative to recording onset)
  175. timeStart = timeWin(1)-(stimDelay);
  176. timeEnd = timeWin(2)-(stimDelay);
  177. timeCut = (1:size(timetr,2));
  178. case {1,2}
  179. timeWin = [round((stimDelay)+timeStart+chirpPeak(s)*1000,4),...
  180. round((stimDelay)+timeEnd+chirpPeak(s)*1000,4)]; % data in this window will be plotted (relative to recording onset)
  181. timeCut = round(timeWin(1)/1000*fs:timeWin(2)/1000*fs+1); % "+1" to reach the proper length, otherwise the index will be 1 point too short since timetr starts at 0 ms
  182. end
  183. dataPlot = dataGrAv(timeCut,filt);
  184. % oscillogram of responses
  185. if plotRespOsciI==1
  186. hold on
  187. box on
  188. % plot standard error
  189. seHiCtrl = dataPlot+dataSe(timeCut,filt);
  190. seLoCtrl = dataPlot-dataSe(timeCut,filt);
  191. seX = [timetr(timeCut),fliplr(timetr(timeCut))];
  192. seY = [seHiCtrl',fliplr(seLoCtrl')];
  193. patch(seX,seY,col,'FaceAlpha',0.2,'EdgeColor','none')
  194. % plot data
  195. plotGrAv = plot(timetr(timeCut),dataPlot,col,'Linewidth',2);
  196. xticks(timeWin(1):xtickSteps:timeWin(2))
  197. set(gca,'XTickLabel',timeStart:xtickSteps:timeEnd)
  198. xlabel('Time [ms]','FontWeight','bold','FontSize',20)
  199. ylabel(ylabelName,'FontWeight','bold','FontSize',20)
  200. set(gca,'FontSize',20,'Linewidth',2,'FontName','Arial')
  201. switch fixedY
  202. case 0
  203. y_limAuto = ylim;
  204. y_min = y_limAuto(1);
  205. y_max = y_limAuto(2);
  206. case 1
  207. y_min = y_lim(1);
  208. y_max = y_lim(2);
  209. ylim(y_lim)
  210. end
  211. xlim([timeWin(1),timeWin(2)])
  212. switch plotWinI
  213. case {1,2}
  214. x_min = timetr(winAllSti{c}(:,:,1))';
  215. x_max = timetr(winAllSti{c}(:,:,2))';
  216. x = cat(3,x_min,x_max,x_max,x_min);
  217. switch fixedY
  218. case 0
  219. y_limAuto = ylim;
  220. y_min = y_limAuto(1);
  221. y_max = y_limAuto(2);
  222. case 1
  223. y_min = y_lim(1);
  224. y_max = y_lim(2);
  225. end
  226. y_temp = [y_min;y_min;y_max;y_max];
  227. y = repmat(y_temp,1,uWin(end));
  228. for r = 1:nResp
  229. for w = uWin
  230. statsV = pV(c,filt,r,w);
  231. % markWin = patch('XData',x(1,w,:),'YData',y(:,w),'EdgeColor','black','EdgeAlpha',1,'FaceColor','none','Linewidth',2,'LineStyle','--'); % window for first response, to indicate area all other responses were compared to
  232. % uistack(markWin,'bottom')
  233. switch plotWinI
  234. case 1
  235. if statsV<0.05
  236. sigWin = patch('XData',x(r,w,:),'YData',y(:,w),'EdgeColor','black','EdgeAlpha',1,'FaceColor','black','FaceAlpha',.2,'Linewidth',2);
  237. else
  238. sigWin = patch('XData',x(r,w,:),'YData',y(:,w),'EdgeColor','black','EdgeAlpha',1,'FaceColor','none','Linewidth',2);
  239. end
  240. case 2
  241. sigWin = patch('XData',x(r,w,:),'YData',y(:,w),'EdgeColor','red','EdgeAlpha',1,'FaceColor','none','Linewidth',2,'LineStyle','--');
  242. end
  243. uistack(sigWin,'bottom')
  244. end
  245. end
  246. end
  247. end
  248. % spectrogram of responses
  249. if plotRespSpecI==1
  250. spectrogram(dataPlot,56,52,[],fs,'yaxis',"MinThreshold",-75)
  251. colormap(cMap)
  252. xLimAuto = xlim;
  253. xlim([xLimAuto(1),timeEnd])
  254. xticks(0:xtickSteps:timeEnd)
  255. ylim([0,yMax])
  256. colorbar('off')
  257. ylabel('Frequency [kHz]','FontWeight','bold')
  258. xlabel('Time [ms]','FontWeight','bold')
  259. box on
  260. set(gca,'FontSize',20,'Linewidth',2,'FontName','Arial')
  261. end
  262. hold on
  263. title([convertStringsToChars(combNameS(s)),'-Freq. Chirp'])
  264. if saveI==1
  265. saveas(gcf,[num2str(c),'_',filtName,'F_',SOAName,'_cutTime',num2str(cutTime),'_to',num2str(timeEnd),'_win',num2str(win),'.jpg'])
  266. saveas(gcf,[num2str(c),'_',filtName,'F_',SOAName,'_cutTime',num2str(cutTime),'_to',num2str(timeEnd),'_win',num2str(win),'.svg'])
  267. % saveas(gcf,[num2str(f),'_',filtName,'_',SOAName,'_cutTime',num2str(cutTime),'_to',num2str(timeEnd),'.fig'])
  268. end
  269. end
  270. end
  271. case 2
  272. for f = 1:1 % once for each stimulation type (block-stim and o1st-stim)
  273. for s = 1:2 % run once for each stimulus combination
  274. c = (f-1)*2+s; % index of dataset to be used
  275. nResp = nResp_cell{c};
  276. % extract data corresponding to current stimulation-condition from
  277. % cell-arrays
  278. dataAv = dataAv_cell{c};
  279. dataGrAv = dataGrAv_cell{c};
  280. dataSe = dataSe_cell{c};
  281. filenames = filenames_stim_cell{c};
  282. recID = recID_cell{c};
  283. bsPos = cell2mat(strfind(filenames,'\')); % find positions of back slashes in filename
  284. startPos = bsPos(:,end); % use last back slash position as starting point
  285. filenames = extractAfter(filenames,startPos);
  286. timetr = round(timetrUnit_cell{c}*1000,4);
  287. stimDur = stimDur_cell{c}(1)*1000;
  288. stimDelay = stimDelay_cell{c}(1)*1000;
  289. stimWin = [stimDelay,stimDelay+stimDur];
  290. nFiles = nFiles_cell{c};
  291. fs_stim = fs_stim_cell{c};
  292. fs = fs_cell{c};
  293. stimCat = stimCat_cell{c};
  294. pts2begin = pts2begin_cell{c};
  295. % process timetrace
  296. switch cutTime
  297. case 0
  298. timeWin = floor([timetr(1),timetr(end)]); % data in this window will be plotted (relative to recording onset)
  299. timeStart = timeWin(1)-(stimDelay);
  300. timeEnd = timeWin(2)-(stimDelay);
  301. timeCut = (1:size(timetr,2));
  302. case {1,2}
  303. timeWin = [round((stimDelay)+timeStart,4),...
  304. round((stimDelay)+timeEnd,4)]; % data in this window will be plotted (relative to recording onset)
  305. timeCut = round(timeWin(1)/1000*fs:(timeWin(2)/1000*fs)+1); % "+1" to reach the proper length, otherwise the index will be 1 point too short since timetr starts at 0 ms
  306. end
  307. for fi = 1:nFiles
  308. figure('NumberTitle','off','Name',[num2str(f),'_',SOAName,'_',convertStringsToChars(filenames(fi))],'Position',[0,0,1500,1300])
  309. set(gca,'FontSize',20,'Linewidth',2,'FontName','Arial')
  310. dataPlot = dataAv(timeCut,fi,filt);
  311. % oscillogram of responses
  312. hold on
  313. box on
  314. % plot data
  315. plotAv = plot(timetr(timeCut),dataPlot,col,'Linewidth',2);
  316. xticks(timeWin(1):xtickSteps:timeWin(2))
  317. set(gca,'XTickLabel',timeStart:xtickSteps:timeEnd)
  318. xlabel('Time [ms]','FontWeight','bold','FontSize',20)
  319. ylabel(ylabelName,'FontWeight','bold','FontSize',20)
  320. set(gca,'FontSize',20,'Linewidth',2,'FontName','Arial')
  321. switch fixedY
  322. case 0
  323. y_limAuto = ylim;
  324. y_min = y_limAuto(1);
  325. y_max = y_limAuto(2);
  326. case 1
  327. y_min = y_lim(1);
  328. y_max = y_lim(2);
  329. ylim(y_lim)
  330. end
  331. xlim([timeWin(1),timeWin(2)])
  332. switch plotWinI
  333. case {1,2}
  334. x_min = timetr(winAllSti{c}(:,:,1))';
  335. x_max = timetr(winAllSti{c}(:,:,2))';
  336. x = cat(3,x_min,x_max,x_max,x_min);
  337. switch fixedY
  338. case 0
  339. y_limAuto = ylim;
  340. y_min = y_limAuto(1);
  341. y_max = y_limAuto(2);
  342. case 1
  343. y_min = y_lim(1);
  344. y_max = y_lim(2);
  345. end
  346. y_temp = [y_min;y_min;y_max;y_max];
  347. y = repmat(y_temp,1,uWin(end));
  348. for r = 1:nResp
  349. for w = uWin
  350. sigWin = patch('XData',x(r,w,:),'YData',y(:,w),'EdgeColor','red','EdgeAlpha',1,'FaceColor','none','Linewidth',2,'LineStyle','--');
  351. uistack(sigWin,'bottom')
  352. end
  353. end
  354. end
  355. hold on
  356. title([convertStringsToChars(combNameS(s)),'-Freq. Chirp'])
  357. end
  358. end
  359. end
  360. end
  361. end
  362. %% plotting: curve fit
  363. switch varType
  364. case 1
  365. titleC = 'ABR Amplitude';
  366. yLabelNameLC = 'ABR p-p Amp. [µV]';
  367. yLabelNameRC = 'Rel. ABR p-p Amp.';
  368. case 2
  369. titleC = 'Peak V Latency';
  370. yLabelNameLC = 'Peak V Latency [ms]';
  371. yLabelNameRC = 'Rel. Peak V Latency';
  372. end
  373. xMin = 0;
  374. xMax = 10;
  375. uWin = win;
  376. if plotCurveI==1
  377. for f = 1:1 % run only for block-stimulation
  378. for s = 1:2 % run once for each stimulus combination
  379. c = (f-1)*2+s; % index of dataset to be used
  380. nResp = nResp_cell{c};
  381. varMax = max(abs(varAvS{c}(filt,1:end-1,uWin)));
  382. varPlot = reshape(varAvS{c}(filt,1:end-1,uWin),1,nResp-1);
  383. sePlot = reshape(varSeS{c}(filt,1:end-1,uWin),1,nResp-1);
  384. figure('NumberTitle','off','Name',[convertStringsToChars(combNameS(c)),'_',SOAName,'_Win',num2str(uWin)],'Position',[0,0,1500,500])
  385. hold on
  386. box on
  387. % plotFit = plot(fV{c,filt,uWin},'k');
  388. plotReg = plot(mdl{varType,c,filt,uWin});
  389. col = plotReg.Color;
  390. plotReg(1).Color = [0,0,0];
  391. plotReg(2).Color = [0,0,0];
  392. plotReg(3).Color = [0,0,0];
  393. plotReg(4).Color = [0,0,0];
  394. mdl{varType,c,filt,uWin}
  395. % plot absolute and relative y axis
  396. yyaxis left % absolute
  397. switch plotSeI
  398. case 0
  399. plotVar = plot(varPlot,'k','LineStyle','none','Marker','.','MarkerSize',30,'Linewidth',2);
  400. case 1
  401. plotVar = errorbar(varPlot,sePlot,'k','LineStyle','none','Marker','.','MarkerSize',30,'Linewidth',2);
  402. end
  403. % adjust ylim
  404. yLimL = ylim;
  405. switch fixedY
  406. case 0
  407. yMinL = yLimL(1)-diff(yLimL)*0.1;
  408. yMaxL = yLimL(2)+diff(yLimL)*0.1;
  409. case 1
  410. yMinL = yMinAbs;
  411. yMaxL = yMaxAbs;
  412. end
  413. ylim([yMinL,yMaxL]);
  414. yLimL = ylim;
  415. ylabel(yLabelNameLC,'FontWeight','bold','FontSize',30)
  416. yyaxis right % relative
  417. ylim(yLimL/varMax)
  418. yLimR = ylim;
  419. ylabel(yLabelNameRC,'FontWeight','bold','FontSize',30)
  420. % fV{varType,c,filt,uWin}
  421. % gofV{varType,c,filt,uWin}
  422. % cosmetics
  423. set(plotReg,'Linewidth',2);
  424. legend([plotVar,plotReg(2),plotReg(3)],'Data','Lin. Reg. Model','95 % Conf. Int.','Location','northeast')
  425. xticks(1:1:nResp-1)
  426. xticklabels(1:int(curveInt)*1:int(curveInt)*nResp-1)
  427. xlim([0,nResp])
  428. xLim = xlim;
  429. xlabel('Repetition in Stim. Train','FontWeight','bold','FontSize',30)
  430. % create text
  431. p = round(mdl{varType,c,filt,uWin}.Coefficients.pValue(2),3);
  432. if p<0.001
  433. ast = '***';
  434. elseif p<0.01
  435. ast = '**';
  436. elseif p<0.05
  437. ast = '*';
  438. else
  439. ast = '';
  440. end
  441. Rs = round(mdl{varType,c,filt,uWin}.Rsquared.Ordinary,3);
  442. txt = ['\itp',ast,'\rm = ',num2str(p),', \itR^2\rm = ',num2str(Rs)];
  443. text((xLim(2)*0.4),yLimR(2)-diff(yLimR)*0.1,txt,'FontSize',30)
  444. title([convertStringsToChars(combNameS(c)),'-Freq. Chirp'])
  445. set(gca,'FontSize',30,'Linewidth',2,'FontName','Arial','YColor','k')
  446. if saveI==1
  447. saveas(gcf,['Reg_',num2str(c),'_',filtName,'F_',SOAName,'_win',num2str(win),'_varType',num2str(varType),'.jpg'])
  448. saveas(gcf,['Reg_',num2str(c),'_',filtName,'F_',SOAName,'_win',num2str(win),'_varType',num2str(varType),'.svg'])
  449. end
  450. end
  451. end
  452. end