


plot_wave() - Plots the ERPs from one or more bins in a GND or GRP
variable in uV or t-scores. Each channel is visualized
on its own axis.
Usage:
>> plot_wave(GND_GRP_or_fname,bins,varargin)
Required Inputs:
GND_GRP_or_fname - A GND/GRP structure variable or the filename of
a GND/GRP structure that has been saved to disk.
To create a GND variable from Kutaslab ERP files (e.g.,
*.nrm files) use avgs2GND.m. To do the same from
EEGLAB *.set files use sets2GND.m. To create a
a GRP structure use GNDs2GRP.m. See Mass Univariate ERP
Toolbox documentation for detailed information about the
format of GND and GRP variables. If you specifiy a filename
be sure to include the file's path, unless the file is
in the current working directory.
bins - [vector] The index of one or more bins that you wish
to visualize. You can visualize up to eight bins.
To see what test results are available, run
headinfo(GND) or headinfo(GRP).
Optional Inputs:
exclude_chans - A cell array of channel labels to exclude from the
visualization (e.g., {'A2','lle','rhe'}). If you wish
to exclude a single channel, you can enter it as a string
(e.g., 'A2') instead of a cell array. Use headinfo.m to see
the channel labels stored in the GND/GRP variable. You cannot
use both this option and 'include_chans' (below).{default:
not used, all channels visualized}
include_chans - A cell array of channel labels to include from the
visualization (e.g., {'Fz','Cz','Pz'}). If you wish
to include a single channel, you can enter it as a string
(e.g., 'Cz') instead of a cell array. Use headinfo.m to see
the channel labels stored in the GND/GRP variable. You cannot
use both this option and 'exclude_chans' (above).{default:
not used, all channels visualized}
time_limits - [min max] Time limits for the x-axes in units of ms
(e.g., [-100 500]. {default: first and last time
point}
time_ticks - [vector] The time points (in units of ms) you want
marked with ticks on the x-axes. {default: MATLAB
default ticks}
tick_labels - ['yes' or 'no'] If 'yes', major time tick marks will
be labeled with their value (in milliseconds).
{default: 'yes'}
cal_amp - The amplitude (in microvolts or t-scores) of the
calibration bar drawn at time=0. {default: a third of
waveform absolute maximum across all shown channels}
cal_width - The width (in units of ms) of the "wings" on the top and
bottom of the calibration bar. {default: scaled to time
window}
wave_limits - [min max] Limits for the y-axis in units of t-scores
or uV (e.g., [-10 15]. {default: slightly bigger than
min and max of waveform}
units - ['uV' or 't'] If 'uV' topographies will be visualized
in units of microvolts. If 't', they will be shown
in t-scores. {default: 'uV'}
legend - ['none','corners' or 'box'] If 'none', no legend will be
drawn. If 'corners', the descriptors for each bin will
be written in the corners of the figure. The color of
the text will correspond to the waveforms it describes.
If 'box' a standard MATLAB legend box will be drawn on
the figure indicating the bin descriptors for each
waveform. Note, if you use 'box,' you can manually move
the position of the legend by clicking-and-dragging the
legend box. {default: 'corners'}
ydir - [1 or -1] If 1, positive is plotted up. Otherwise,
positive is represented as down. {default: -1}
fig_id - [integer] The index # of the MATLAB figure in which
the diagram will be produced. Useful for overwriting
old figures. {default: lowest unused index}
label_size - [integer] The font size of the channel labels on top of the
calibration bars. If 0, channels labels are not drawn.
{default: 8}
title - [string] The plot title. {default: none}
verblevel - An integer specifiying the amount of information you want
this function to provide about what it is doing during runtime.
Options are:
0 - quiet, only show errors, warnings, and EEGLAB reports
1 - stuff anyone should probably know
2 - stuff you should know the first time you start working
with a data set {default value}
3 - stuff that might help you debug (show all
reports)
Global Variable:
VERBLEVEL - Mass Univariate ERP Toolbox level of verbosity (i.e., tells functions
how much to report about what they're doing during
runtime) set by the optional function argument 'verblevel'
Notes:
-The printed/exported figure will have the same dimensions as the figure
on the display. Thus you can undo figure clutter by re-sizing it.
Author:
David Groppe
Kutaslab, 12/2010


0001 % plot_wave() - Plots the ERPs from one or more bins in a GND or GRP 0002 % variable in uV or t-scores. Each channel is visualized 0003 % on its own axis. 0004 % 0005 % Usage: 0006 % >> plot_wave(GND_GRP_or_fname,bins,varargin) 0007 % 0008 % Required Inputs: 0009 % GND_GRP_or_fname - A GND/GRP structure variable or the filename of 0010 % a GND/GRP structure that has been saved to disk. 0011 % To create a GND variable from Kutaslab ERP files (e.g., 0012 % *.nrm files) use avgs2GND.m. To do the same from 0013 % EEGLAB *.set files use sets2GND.m. To create a 0014 % a GRP structure use GNDs2GRP.m. See Mass Univariate ERP 0015 % Toolbox documentation for detailed information about the 0016 % format of GND and GRP variables. If you specifiy a filename 0017 % be sure to include the file's path, unless the file is 0018 % in the current working directory. 0019 % bins - [vector] The index of one or more bins that you wish 0020 % to visualize. You can visualize up to eight bins. 0021 % To see what test results are available, run 0022 % headinfo(GND) or headinfo(GRP). 0023 % 0024 % Optional Inputs: 0025 % exclude_chans - A cell array of channel labels to exclude from the 0026 % visualization (e.g., {'A2','lle','rhe'}). If you wish 0027 % to exclude a single channel, you can enter it as a string 0028 % (e.g., 'A2') instead of a cell array. Use headinfo.m to see 0029 % the channel labels stored in the GND/GRP variable. You cannot 0030 % use both this option and 'include_chans' (below).{default: 0031 % not used, all channels visualized} 0032 % include_chans - A cell array of channel labels to include from the 0033 % visualization (e.g., {'Fz','Cz','Pz'}). If you wish 0034 % to include a single channel, you can enter it as a string 0035 % (e.g., 'Cz') instead of a cell array. Use headinfo.m to see 0036 % the channel labels stored in the GND/GRP variable. You cannot 0037 % use both this option and 'exclude_chans' (above).{default: 0038 % not used, all channels visualized} 0039 % time_limits - [min max] Time limits for the x-axes in units of ms 0040 % (e.g., [-100 500]. {default: first and last time 0041 % point} 0042 % time_ticks - [vector] The time points (in units of ms) you want 0043 % marked with ticks on the x-axes. {default: MATLAB 0044 % default ticks} 0045 % tick_labels - ['yes' or 'no'] If 'yes', major time tick marks will 0046 % be labeled with their value (in milliseconds). 0047 % {default: 'yes'} 0048 % cal_amp - The amplitude (in microvolts or t-scores) of the 0049 % calibration bar drawn at time=0. {default: a third of 0050 % waveform absolute maximum across all shown channels} 0051 % cal_width - The width (in units of ms) of the "wings" on the top and 0052 % bottom of the calibration bar. {default: scaled to time 0053 % window} 0054 % wave_limits - [min max] Limits for the y-axis in units of t-scores 0055 % or uV (e.g., [-10 15]. {default: slightly bigger than 0056 % min and max of waveform} 0057 % units - ['uV' or 't'] If 'uV' topographies will be visualized 0058 % in units of microvolts. If 't', they will be shown 0059 % in t-scores. {default: 'uV'} 0060 % legend - ['none','corners' or 'box'] If 'none', no legend will be 0061 % drawn. If 'corners', the descriptors for each bin will 0062 % be written in the corners of the figure. The color of 0063 % the text will correspond to the waveforms it describes. 0064 % If 'box' a standard MATLAB legend box will be drawn on 0065 % the figure indicating the bin descriptors for each 0066 % waveform. Note, if you use 'box,' you can manually move 0067 % the position of the legend by clicking-and-dragging the 0068 % legend box. {default: 'corners'} 0069 % ydir - [1 or -1] If 1, positive is plotted up. Otherwise, 0070 % positive is represented as down. {default: -1} 0071 % fig_id - [integer] The index # of the MATLAB figure in which 0072 % the diagram will be produced. Useful for overwriting 0073 % old figures. {default: lowest unused index} 0074 % label_size - [integer] The font size of the channel labels on top of the 0075 % calibration bars. If 0, channels labels are not drawn. 0076 % {default: 8} 0077 % title - [string] The plot title. {default: none} 0078 % verblevel - An integer specifiying the amount of information you want 0079 % this function to provide about what it is doing during runtime. 0080 % Options are: 0081 % 0 - quiet, only show errors, warnings, and EEGLAB reports 0082 % 1 - stuff anyone should probably know 0083 % 2 - stuff you should know the first time you start working 0084 % with a data set {default value} 0085 % 3 - stuff that might help you debug (show all 0086 % reports) 0087 % 0088 % Global Variable: 0089 % VERBLEVEL - Mass Univariate ERP Toolbox level of verbosity (i.e., tells functions 0090 % how much to report about what they're doing during 0091 % runtime) set by the optional function argument 'verblevel' 0092 % 0093 % Notes: 0094 % -The printed/exported figure will have the same dimensions as the figure 0095 % on the display. Thus you can undo figure clutter by re-sizing it. 0096 % 0097 % 0098 % Author: 0099 % David Groppe 0100 % Kutaslab, 12/2010 0101 0102 %%%%%%%%%%%%%%%% REVISION LOG %%%%%%%%%%%%%%%%% 0103 % ?/??/2010- 0104 0105 %%%%%%%%%%%%%%%% FUTURE WORK %%%%%%%%%%%%%%%%% 0106 % 0107 0108 function plot_wave(GND_GRP_or_fname,bins,varargin) 0109 0110 p=inputParser; 0111 p.addRequired('GND_GRP_or_fname',@(x) isstruct(x) || ischar(x)); 0112 p.addRequired('bins',@isnumeric); 0113 p.addParamValue('exclude_chans',[],@(x) ischar(x) || iscell(x)); 0114 p.addParamValue('include_chans',[],@(x) ischar(x) || iscell(x)); 0115 p.addParamValue('time_ticks',[],@isnumeric); 0116 p.addParamValue('cal_amp',[],@(x) isnumeric(x) && (length(x)==1)); 0117 p.addParamValue('cal_width',[],@(x) isnumeric(x) && (length(x)==1)); 0118 p.addParamValue('fig_id',[],@(x) isnumeric(x) && (length(x)==1)); 0119 p.addParamValue('verblevel',[],@(x) isnumeric(x) && (length(x)==1)); 0120 p.addParamValue('time_limits',[],@(x) isnumeric(x) && (length(x)==2)); 0121 p.addParamValue('wave_limits',[],@(x) isnumeric(x) && (length(x)==2)); 0122 p.addParamValue('ydir',-1,@(x) isnumeric(x) && (length(x)==1)); 0123 p.addParamValue('title',[],@(x) ischar(x)); 0124 p.addParamValue('units','uV',@ischar); 0125 p.addParamValue('legend','corners',@(x) ischar(x) && (strcmpi('corners',x) || strcmpi('box',x) || strcmpi('none',x))); 0126 p.addParamValue('tick_labels','yes',@ischar); 0127 p.addParamValue('label_size',8,@(x) isnumeric(x) && (length(x)==1)); 0128 0129 p.parse(GND_GRP_or_fname,bins,varargin{:}); 0130 0131 0132 % Manage VERBLEVEL 0133 if isempty(p.Results.verblevel), 0134 VERBLEVEL=2; %not global, just local 0135 else 0136 VERBLEVEL=p.Results.verblevel; 0137 end 0138 0139 tick_labels=str2bool(p.Results.tick_labels); 0140 0141 %load GND/GRP variable if a filename was passed 0142 if ischar(p.Results.GND_GRP_or_fname), 0143 if VERBLEVEL, 0144 fprintf('Loading GND struct from file %s.\n',p.Results.GND_GRP_or_fname); 0145 end 0146 load(p.Results.GND_GRP_or_fname,'-MAT'); 0147 if ~exist('GND','var') && ~exist('GRP','var') 0148 error('File %s does not contain a GND or GRP variable.',p.Results.GND_GRP_or_fname); 0149 end 0150 if exist('GRP','var'), 0151 GND=GRP; %for simplicity GRP variables are re-named GND 0152 clear GRP; 0153 end 0154 else 0155 GND=p.Results.GND_GRP_or_fname; %for simplicity GRP variables are re-named GND 0156 end 0157 0158 %% Figure out which channels to ignore if any 0159 %But first make sure exclude & include options were not both used. 0160 if ~isempty(p.Results.include_chans) && ~isempty(p.Results.exclude_chans) 0161 error('You cannot use BOTH ''include_chans'' and ''exclude_chans'' options.'); 0162 end 0163 if ischar(p.Results.exclude_chans), 0164 exclude_chans{1}=p.Results.exclude_chans; 0165 elseif isempty(p.Results.exclude_chans) 0166 exclude_chans=[]; 0167 else 0168 exclude_chans=p.Results.exclude_chans; 0169 end 0170 if ischar(p.Results.include_chans), 0171 include_chans{1}=p.Results.include_chans; 0172 elseif isempty(p.Results.include_chans) 0173 include_chans=[]; 0174 else 0175 include_chans=p.Results.include_chans; 0176 end 0177 0178 n_chan=length(GND.chanlocs); 0179 % exclude and include chan options 0180 if ~isempty(exclude_chans), 0181 ignore_chans=zeros(1,length(exclude_chans)); %preallocate mem 0182 ct=0; 0183 for x=1:length(exclude_chans), 0184 found=0; 0185 for c=1:n_chan, 0186 if strcmpi(exclude_chans{x},GND.chanlocs(c).labels), 0187 found=1; 0188 ct=ct+1; 0189 ignore_chans(ct)=c; 0190 end 0191 end 0192 if ~found, 0193 watchit(sprintf('I attempted to exclude %s. However no such electrode was found in GND variable.', ... 0194 exclude_chans{x})); 0195 end 0196 end 0197 ignore_chans=ignore_chans(1:ct); 0198 use_chans=setdiff(1:n_chan,ignore_chans); 0199 elseif ~isempty(include_chans), 0200 use_chans=zeros(1,length(include_chans)); %preallocate mem 0201 ct=0; 0202 for x=1:length(include_chans), 0203 found=0; 0204 for c=1:n_chan, 0205 if strcmpi(include_chans{x},GND.chanlocs(c).labels), 0206 found=1; 0207 ct=ct+1; 0208 use_chans(ct)=c; 0209 end 0210 end 0211 if ~found, 0212 watchit(sprintf('I attempted to include %s. However no such electrode was found in GND variable.', ... 0213 include_chans{x})); 0214 end 0215 end 0216 use_chans=use_chans(1:ct); 0217 else 0218 use_chans=1:n_chan; 0219 end 0220 0221 n_use_bins=length(bins); 0222 if max(bins)>length(GND.bin_info) 0223 error('There are only %d bins in this GND/GRP variable, but you asked to plot Bin %d.\n', ... 0224 length(GND.bin_info),max(bins)); 0225 elseif min(bins)<1, 0226 error('All elements of the "bins" argument must be greater than 0.'); 0227 end 0228 if isempty(p.Results.fig_id) 0229 fig_h=figure; 0230 else 0231 fig_h=figure(p.Results.fig_id); clf; 0232 end 0233 if n_use_bins>1, 0234 fig_title=[GND.exp_desc ' (Bins ' int2str(bins) ')']; 0235 else 0236 fig_title=[GND.exp_desc ' (Bin ' int2str(bins) ')']; 0237 end 0238 set(fig_h,'name',fig_title,'paperpositionmode','auto'); 0239 %setting paperpositionmode to 'auto' means that if the figure is manually 0240 %resized, the printed version of the figure will reflect the whatever the 0241 %shown size was (at the time of printing) 0242 0243 %Waveform time limits 0244 if isempty(p.Results.time_limits), 0245 time_lim=[GND.time_pts(1) GND.time_pts(end)]; 0246 else 0247 time_lim=p.Results.time_limits; 0248 end 0249 0250 %Waveform amplitude limits 0251 tpt(1)=find_tpt(time_lim(1),GND.time_pts); 0252 tpt(2)=find_tpt(time_lim(2),GND.time_pts); 0253 if strcmpi(p.Results.units,'uV'), 0254 dat=GND.grands(use_chans,tpt(1):tpt(2),bins); 0255 else 0256 dat=GND.grands_t(use_chans,tpt(1):tpt(2),bins); 0257 end 0258 mx_wav=max(max(max(dat))); 0259 mn_wav=min(min(min(dat))); 0260 mx_abs=max(abs([mx_wav mn_wav])); 0261 if isempty(p.Results.cal_amp), 0262 cal_amp=round(mx_abs/3); 0263 else 0264 cal_amp=abs(p.Results.cal_amp); 0265 end 0266 if isempty(p.Results.wave_limits), 0267 y_lim(1)=min([mn_wav -cal_amp])*1.1; 0268 y_lim(2)=max([mx_wav cal_amp])*1.1; 0269 else 0270 y_lim=p.Results.wave_limits; 0271 end 0272 0273 0274 %% Plot Waveforms 0275 n_use_chans=length(use_chans); 0276 n_tall=floor(sqrt(n_use_chans+1)); %add one axis for legend 0277 n_wide=ceil((n_use_chans+1)/n_tall); %add one axis for legend 0278 if n_use_bins>8, 0279 error('You are a crazy person! You can''t plot more than eight waveforms on a single plot.'); 0280 end 0281 colors={'r','b','m','c','g','w','y'}; 0282 lwidth_plt=1; 0283 if isempty(p.Results.cal_width) 0284 cal_width=(time_lim(2)-time_lim(1))/20; 0285 else 0286 cal_width=p.Results.cal_width; 0287 end 0288 if isempty(p.Results.time_ticks) 0289 rng=time_lim(2)-time_lim(1); 0290 delt=rnd_orderofmag(rng/5); 0291 ticks=time_lim(1):delt:0; 0292 ticks=[ticks [0:delt:time_lim(2)]]; 0293 else 0294 ticks=p.Results.time_ticks; 0295 end 0296 tck_ht=cal_amp/5; 0297 bin_ct=0; 0298 bin_desc=cell(1,n_use_bins); 0299 for b=bins, 0300 bin_ct=bin_ct+1; 0301 bin_desc{bin_ct}=GND.bin_info(b).bindesc; 0302 for c=1:n_use_chans, 0303 subplot(n_tall,n_wide,c); 0304 if b==bins(1), 0305 %first wave for this channel 0306 0307 %wave amp=0 line 0308 h=plot([time_lim(1) time_lim(2)],[0 0],'k'); 0309 set(h,'linewidth',lwidth_plt); 0310 hold on; 0311 %verticle part of cal bar 0312 h=plot([0 0],[-1 1]*cal_amp,'k'); 0313 set(h,'linewidth',lwidth_plt); 0314 0315 %horizontal parts of cal bar 0316 h=plot([-cal_width cal_width],[1 1]*cal_amp,'k'); 0317 set(h,'linewidth',lwidth_plt); 0318 h=plot([-cal_width cal_width],[-1 -1]*cal_amp,'k'); 0319 set(h,'linewidth',lwidth_plt); 0320 0321 %time ticks 0322 tk_ct=0; 0323 for a=ticks, 0324 tk_ct=tk_ct+1; 0325 if mod(tk_ct,2) 0326 %plot every other tick as half height 0327 h=plot([a a],[-tck_ht tck_ht]*.5,'k'); 0328 else 0329 h=plot([a a],[-tck_ht tck_ht],'k'); 0330 last_lab=a; %for plotting time tick labels below 0331 end 0332 set(h,'linewidth',lwidth_plt); 0333 end 0334 0335 %Channel label 0336 if p.Results.label_size>0, 0337 tt=text(0,sign(p.Results.ydir)*cal_amp*1.4,GND.chanlocs(use_chans(c)).labels); 0338 set(tt,'horizontalalignment','center','fontsize',p.Results.label_size, ... 0339 'fontweight','bold'); 0340 end 0341 0342 set(gca,'visible','off'); 0343 if p.Results.ydir<0 0344 set(gca,'ydir','reverse'); 0345 end 0346 end 0347 0348 if strcmpi(p.Results.units,'uV'), 0349 dat=GND.grands(use_chans(c),:,b); 0350 else 0351 dat=GND.grands_t(use_chans(c),:,b); 0352 end 0353 plot(GND.time_pts,dat,colors{bin_ct}); 0354 0355 if b==bins(end), 0356 %set limits 0357 axis([time_lim y_lim]); 0358 end 0359 end 0360 0361 if strcmpi(p.Results.legend,'box') && (b==bins(end)) 0362 [dummy obj_hndls]=legend('best',bin_desc); 0363 for bb=1:n_use_bins, 0364 set(obj_hndls(bb*2+n_use_bins-1),'color',colors{bb}); 0365 end 0366 end 0367 end 0368 0369 %% Plot empty axis for denoting tick marks and voltage size 0370 subplot(n_tall,n_wide,n_use_chans+1); 0371 0372 if p.Results.label_size>0, 0373 unit_size=p.Results.label_size; 0374 else 0375 unit_size=8; 0376 end 0377 0378 %wave amp=0 line 0379 h=plot([time_lim(1) time_lim(2)],[0 0],'k'); 0380 set(h,'linewidth',lwidth_plt); 0381 hold on; 0382 %verticle part of cal bar 0383 h=plot([0 0],[-1 1]*cal_amp,'k'); 0384 set(h,'linewidth',lwidth_plt); 0385 0386 %horizontal parts of cal bar 0387 h=plot([-cal_width cal_width],[1 1]*cal_amp,'k'); 0388 set(h,'linewidth',lwidth_plt); 0389 h=plot([-cal_width cal_width],[-1 -1]*cal_amp,'k'); 0390 set(h,'linewidth',lwidth_plt); 0391 0392 %time ticks 0393 tk_ct=0; 0394 for a=ticks, 0395 tk_ct=tk_ct+1; 0396 if mod(tk_ct,2) 0397 %plot every other tick as half height 0398 h=plot([a a],[-tck_ht tck_ht]*.5,'k'); 0399 else 0400 h=plot([a a],[-tck_ht tck_ht],'k'); 0401 end 0402 set(h,'linewidth',lwidth_plt); 0403 0404 %Tick labels 0405 if ~mod(tk_ct,2) && a, 0406 if tick_labels, 0407 if a==last_lab 0408 tt=text(a,-tck_ht*3,[' ' int2str(a) ' ms']); 0409 else 0410 tt=text(a,-tck_ht*3,int2str(a)); 0411 end 0412 set(tt,'horizontalalignment','center','fontsize',unit_size, ... 0413 'fontweight','bold'); 0414 end 0415 end 0416 end 0417 0418 if p.Results.ydir<0 0419 set(gca,'ydir','reverse'); 0420 sign_label='-'; 0421 else 0422 sign_label=[]; 0423 end 0424 0425 %Amplitude label 0426 if strcmpi(p.Results.units,'uV'), 0427 unit_label='\muV'; 0428 else 0429 unit_label='t'; 0430 end 0431 tt=text(0,sign(p.Results.ydir)*cal_amp*1.4,[sign_label num2str(cal_amp) ' ' unit_label]); 0432 set(tt,'horizontalalignment','center','fontsize',unit_size,'fontweight','bold'); 0433 0434 set(gca,'visible','off'); 0435 axis([time_lim y_lim]); 0436 0437 %Plot legend 0438 if strcmpi(p.Results.legend,'corners') 0439 leg_coorX=[.05 .05 .55 .55]; 0440 leg_coorY=[.1 .05 .1 .05]; 0441 bin_ct=0; 0442 for b=bins, 0443 bin_ct=bin_ct+1; 0444 tt=textsc(leg_coorX(bin_ct),leg_coorY(bin_ct),GND.bin_info(b).bindesc); 0445 set(tt,'horizontalalignment','left','fontsize',12,'color',colors{bin_ct}); 0446 end 0447 end 0448 0449 if ~isempty(p.Results.title), 0450 tt=textsc(p.Results.title,'title'); 0451 set(tt,'fontweight','bold','fontsize',14); 0452 end 0453 0454 % 0455 %% %%%%%%%%%%%%%%%%%%%%% function str2bool() %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0456 % 0457 function bool=str2bool(str) 0458 %function bool=str2bool(str) 0459 0460 if ischar(str), 0461 if strcmpi(str,'yes') || strcmpi(str,'y') 0462 bool=1; 0463 else 0464 bool=0; 0465 end 0466 else 0467 bool=str; 0468 end 0469