|
a |
|
b/code/preprocessing/EEG/fastica/icaplot.m |
|
|
1 |
function icaplot(mode, varargin); |
|
|
2 |
%ICAPLOT - plot signals in various ways |
|
|
3 |
% |
|
|
4 |
% ICAPLOT is mainly for plottinf and comparing the mixed signals and |
|
|
5 |
% separated ica-signals. |
|
|
6 |
% |
|
|
7 |
% ICAPLOT has many different modes. The first parameter of the function |
|
|
8 |
% defines the mode. Other parameters and their order depends on the |
|
|
9 |
% mode. The explanation for the more common parameters is in the end. |
|
|
10 |
% |
|
|
11 |
% Classic |
|
|
12 |
% icaplot('classic', s1, n1, range, xrange, titlestr) |
|
|
13 |
% |
|
|
14 |
% Plots the signals in the same manner as the FASTICA and FASTICAG |
|
|
15 |
% programs do. All the signals are plotted in their own axis. |
|
|
16 |
% |
|
|
17 |
% Complot |
|
|
18 |
% icaplot('complot', s1, n1, range, xrange, titlestr) |
|
|
19 |
% |
|
|
20 |
% The signals are plotted on the same axis. This is good for |
|
|
21 |
% visualization of the shape of the signals. The scale of the signals |
|
|
22 |
% has been altered so that they all fit nicely. |
|
|
23 |
% |
|
|
24 |
% Histogram |
|
|
25 |
% icaplot('histogram', s1, n1, range, bins, style) |
|
|
26 |
% |
|
|
27 |
% The histogram of the signals is plotted. The number of bins can be |
|
|
28 |
% specified with 'bins'-parameter. The style for the histograms can |
|
|
29 |
% be either 'bar' (default) of 'line'. |
|
|
30 |
% |
|
|
31 |
% Scatter |
|
|
32 |
% icaplot('scatter', s1, n1, s2, n2, range, titlestr, s1label, |
|
|
33 |
% s2label, markerstr) |
|
|
34 |
% |
|
|
35 |
% A scatterplot is plotted so that the signal 1 is the 'X'-variable |
|
|
36 |
% and the signal 2 is the 'Y'-variable. The 'markerstr' can be used |
|
|
37 |
% to specify the maker used in the plot. The format for 'markerstr' |
|
|
38 |
% is the same as for Matlab's PLOT. |
|
|
39 |
% |
|
|
40 |
% Compare |
|
|
41 |
% icaplot('compare', s1, n1, s2, n2, range, xrange, titlestr, |
|
|
42 |
% s1label, s2label) |
|
|
43 |
% |
|
|
44 |
% This for for comparing two signals. The main used in this context |
|
|
45 |
% would probably be to see how well the separated ICA-signals explain |
|
|
46 |
% the observed mixed signals. The s2 signals are first scaled with |
|
|
47 |
% REGRESS function. |
|
|
48 |
% |
|
|
49 |
% Compare - Sum |
|
|
50 |
% icaplot('sum', s1, n1, s2, n2, range, xrange, titlestr, s1label, |
|
|
51 |
% s2label) |
|
|
52 |
% |
|
|
53 |
% The same as Compare, but this time the signals in s2 (specified by |
|
|
54 |
% n2) are summed together. |
|
|
55 |
% |
|
|
56 |
% Compare - Sumerror |
|
|
57 |
% icaplot('sumerror', s1, n1, s2, n2, range, xrange, titlestr, |
|
|
58 |
% s1label, s2label) |
|
|
59 |
% |
|
|
60 |
% The same as Compare - Sum, but also the 'error' between the signal |
|
|
61 |
% 1 and the summed IC's is plotted. |
|
|
62 |
% |
|
|
63 |
% |
|
|
64 |
% More common parameters |
|
|
65 |
% The signals to be plotted are in matrices s1 and s2. The n1 and n2 |
|
|
66 |
% are used to tell the index of the signal or signals to be plotted |
|
|
67 |
% from s1 or s2. If n1 or n2 has a value of 0, then all the signals |
|
|
68 |
% from corresponding matrix will be plotted. The values for n1 and n2 |
|
|
69 |
% can also be vectors (like: [1 3 4]) In some casee if there are more |
|
|
70 |
% than 1 signal to be plotted from s1 or s2 then the plot will |
|
|
71 |
% contain as many subplots as are needed. |
|
|
72 |
% |
|
|
73 |
% The range of the signals to be plotted can be limited with |
|
|
74 |
% 'range'-parameter. It's value is a vector ( 10000:15000 ). If range |
|
|
75 |
% is 0, then the whole range will be plotted. |
|
|
76 |
% |
|
|
77 |
% The 'xrange' is used to specify only the labels used on the |
|
|
78 |
% x-axis. The value of 'xrange' is a vector containing the x-values |
|
|
79 |
% for the plots or [start end] for begin and end of the range |
|
|
80 |
% ( 10000:15000 or [10 15] ). If xrange is 0, then value of range |
|
|
81 |
% will be used for x-labels. |
|
|
82 |
% |
|
|
83 |
% You can give a title for the plot with 'titlestr'. Also the |
|
|
84 |
% 's1label' and 's2label' are used to give more meaningfull label for |
|
|
85 |
% the signals. |
|
|
86 |
% |
|
|
87 |
% Lastly, you can omit some of the arguments from the and. You will |
|
|
88 |
% have to give values for the signal matrices (s1, s2) and the |
|
|
89 |
% indexes (n1, n2) |
|
|
90 |
|
|
|
91 |
% @(#)$Id$ |
|
|
92 |
|
|
|
93 |
switch mode |
|
|
94 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
95 |
% 'dispsig' is to replace the old DISPSIG |
|
|
96 |
% '' & 'classic' are just another names - '' quite short one :-) |
|
|
97 |
case {'', 'classic', 'dispsig'} |
|
|
98 |
% icaplot(mode, s1, n1, range, xrange, titlestr) |
|
|
99 |
if length(varargin) < 1, error('Not enough arguments.'); end |
|
|
100 |
if length(varargin) < 5, titlestr = '';else titlestr = varargin{5}; end |
|
|
101 |
if length(varargin) < 4, xrange = 0;else xrange = varargin{4}; end |
|
|
102 |
if length(varargin) < 3, range = 0;else range = varargin{3}; end |
|
|
103 |
if length(varargin) < 2, n1 = 0;else n1 = varargin{2}; end |
|
|
104 |
s1 = varargin{1}; |
|
|
105 |
range=chkrange(range, s1); |
|
|
106 |
xrange=chkxrange(xrange, range); |
|
|
107 |
n1=chkn(n1, s1); |
|
|
108 |
|
|
|
109 |
clf; |
|
|
110 |
|
|
|
111 |
numSignals = size(n1, 2); |
|
|
112 |
for i = 1:numSignals, |
|
|
113 |
subplot(numSignals, 1, i); |
|
|
114 |
plot(xrange, s1(n1(i), range)); |
|
|
115 |
end |
|
|
116 |
subplot(numSignals,1, 1); |
|
|
117 |
if (~isempty(titlestr)) |
|
|
118 |
title(titlestr); |
|
|
119 |
end |
|
|
120 |
|
|
|
121 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
122 |
case 'complot' |
|
|
123 |
% icaplot(mode, s1, n1, range, xrange, titlestr) |
|
|
124 |
if length(varargin) < 1, error('Not enough arguments.'); end |
|
|
125 |
if length(varargin) < 5, titlestr = '';else titlestr = varargin{5}; end |
|
|
126 |
if length(varargin) < 4, xrange = 0;else xrange = varargin{4}; end |
|
|
127 |
if length(varargin) < 3, range = 0;else range = varargin{3}; end |
|
|
128 |
if length(varargin) < 2, n1 = 0;else n1 = varargin{2}; end |
|
|
129 |
s1 = remmean(varargin{1}); |
|
|
130 |
range=chkrange(range, s1); |
|
|
131 |
xrange=chkxrange(xrange, range); |
|
|
132 |
n1=chkn(n1, s1); |
|
|
133 |
|
|
|
134 |
for i = 1:size(n1, 2) |
|
|
135 |
S1(i, :) = s1(n1(i), range); |
|
|
136 |
end |
|
|
137 |
|
|
|
138 |
alpha = mean(max(S1')-min(S1')); |
|
|
139 |
for i = 1:size(n1,2) |
|
|
140 |
S2(i,:) = S1(i,:) - alpha*(i-1)*ones(size(S1(1,:))); |
|
|
141 |
end |
|
|
142 |
|
|
|
143 |
plot(xrange, S2'); |
|
|
144 |
axis([min(xrange) max(xrange) min(min(S2)) max(max(S2)) ]); |
|
|
145 |
|
|
|
146 |
set(gca,'YTick',(-size(S1,1)+1)*alpha:alpha:0); |
|
|
147 |
set(gca,'YTicklabel',fliplr(n1)); |
|
|
148 |
|
|
|
149 |
if (~isempty(titlestr)) |
|
|
150 |
title(titlestr); |
|
|
151 |
end |
|
|
152 |
|
|
|
153 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
154 |
case 'histogram' |
|
|
155 |
% icaplot(mode, s1, n1, range, bins, style) |
|
|
156 |
if length(varargin) < 1, error('Not enough arguments.'); end |
|
|
157 |
if length(varargin) < 5, style = 'bar';else style = varargin{5}; end |
|
|
158 |
if length(varargin) < 4, bins = 10;else bins = varargin{4}; end |
|
|
159 |
if length(varargin) < 3, range = 0;else range = varargin{3}; end |
|
|
160 |
if length(varargin) < 2, n1 = 0;else n1 = varargin{2}; end |
|
|
161 |
s1 = varargin{1}; |
|
|
162 |
range = chkrange(range, s1); |
|
|
163 |
n1 = chkn(n1, s1); |
|
|
164 |
|
|
|
165 |
numSignals = size(n1, 2); |
|
|
166 |
rows = floor(sqrt(numSignals)); |
|
|
167 |
columns = ceil(sqrt(numSignals)); |
|
|
168 |
while (rows * columns < numSignals) |
|
|
169 |
columns = columns + 1; |
|
|
170 |
end |
|
|
171 |
|
|
|
172 |
switch style |
|
|
173 |
case {'', 'bar'} |
|
|
174 |
for i = 1:numSignals, |
|
|
175 |
subplot(rows, columns, i); |
|
|
176 |
hist(s1(n1(i), range), bins); |
|
|
177 |
title(int2str(n1(i))); |
|
|
178 |
drawnow; |
|
|
179 |
end |
|
|
180 |
|
|
|
181 |
case 'line' |
|
|
182 |
for i = 1:numSignals, |
|
|
183 |
subplot(rows, columns, i); |
|
|
184 |
[Y, X]=hist(s1(n1(i), range), bins); |
|
|
185 |
plot(X, Y); |
|
|
186 |
title(int2str(n1(i))); |
|
|
187 |
drawnow; |
|
|
188 |
end |
|
|
189 |
otherwise |
|
|
190 |
fprintf('Unknown style.\n') |
|
|
191 |
end |
|
|
192 |
|
|
|
193 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
194 |
case 'scatter' |
|
|
195 |
% icaplot(mode, s1, n1, s2, n2, range, titlestr, xlabelstr, ylabelstr, markerstr) |
|
|
196 |
if length(varargin) < 4, error('Not enough arguments.'); end |
|
|
197 |
if length(varargin) < 9, markerstr = '.';else markerstr = varargin{9}; end |
|
|
198 |
if length(varargin) < 8, ylabelstr = 'Signal 2';else ylabelstr = varargin{8}; end |
|
|
199 |
if length(varargin) < 7, xlabelstr = 'Signal 1';else xlabelstr = varargin{7}; end |
|
|
200 |
if length(varargin) < 6, titlestr = '';else titlestr = varargin{6}; end |
|
|
201 |
if length(varargin) < 5, range = 0;else range = varargin{5}; end |
|
|
202 |
n2 = varargin{4}; |
|
|
203 |
s2 = varargin{3}; |
|
|
204 |
n1 = varargin{2}; |
|
|
205 |
s1 = varargin{1}; |
|
|
206 |
range = chkrange(range, s1); |
|
|
207 |
n1 = chkn(n1, s1); |
|
|
208 |
n2 = chkn(n2, s2); |
|
|
209 |
|
|
|
210 |
rows = size(n1, 2); |
|
|
211 |
columns = size(n2, 2); |
|
|
212 |
for r = 1:rows |
|
|
213 |
for c = 1:columns |
|
|
214 |
subplot(rows, columns, (r-1)*columns + c); |
|
|
215 |
plot(s1(n1(r), range),s2(n2(c), range),markerstr); |
|
|
216 |
if (~isempty(titlestr)) |
|
|
217 |
title(titlestr); |
|
|
218 |
end |
|
|
219 |
if (rows*columns == 1) |
|
|
220 |
xlabel(xlabelstr); |
|
|
221 |
ylabel(ylabelstr); |
|
|
222 |
else |
|
|
223 |
xlabel([xlabelstr ' (' int2str(n1(r)) ')']); |
|
|
224 |
ylabel([ylabelstr ' (' int2str(n2(c)) ')']); |
|
|
225 |
end |
|
|
226 |
drawnow; |
|
|
227 |
end |
|
|
228 |
end |
|
|
229 |
|
|
|
230 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
231 |
case {'compare', 'sum', 'sumerror'} |
|
|
232 |
% icaplot(mode, s1, n1, s2, n2, range, xrange, titlestr, s1label, s2label) |
|
|
233 |
if length(varargin) < 4, error('Not enough arguments.'); end |
|
|
234 |
if length(varargin) < 9, s2label = 'IC';else s2label = varargin{9}; end |
|
|
235 |
if length(varargin) < 8, s1label = 'Mix';else s1label = varargin{8}; end |
|
|
236 |
if length(varargin) < 7, titlestr = '';else titlestr = varargin{7}; end |
|
|
237 |
if length(varargin) < 6, xrange = 0;else xrange = varargin{6}; end |
|
|
238 |
if length(varargin) < 5, range = 0;else range = varargin{5}; end |
|
|
239 |
s1 = varargin{1}; |
|
|
240 |
n1 = varargin{2}; |
|
|
241 |
s2 = varargin{3}; |
|
|
242 |
n2 = varargin{4}; |
|
|
243 |
range = chkrange(range, s1); |
|
|
244 |
xrange = chkxrange(xrange, range); |
|
|
245 |
n1 = chkn(n1, s1); |
|
|
246 |
n2 = chkn(n2, s2); |
|
|
247 |
|
|
|
248 |
numSignals = size(n1, 2); |
|
|
249 |
if (numSignals > 1) |
|
|
250 |
externalLegend = 1; |
|
|
251 |
else |
|
|
252 |
externalLegend = 0; |
|
|
253 |
end |
|
|
254 |
|
|
|
255 |
rows = floor(sqrt(numSignals+externalLegend)); |
|
|
256 |
columns = ceil(sqrt(numSignals+externalLegend)); |
|
|
257 |
while (rows * columns < (numSignals+externalLegend)) |
|
|
258 |
columns = columns + 1; |
|
|
259 |
end |
|
|
260 |
|
|
|
261 |
clf; |
|
|
262 |
|
|
|
263 |
for j = 1:numSignals |
|
|
264 |
subplot(rows, columns, j); |
|
|
265 |
switch mode |
|
|
266 |
case 'compare' |
|
|
267 |
plotcompare(s1, n1(j), s2,n2, range, xrange); |
|
|
268 |
[legendtext,legendstyle]=legendcompare(n1(j),n2,s1label,s2label,externalLegend); |
|
|
269 |
case 'sum' |
|
|
270 |
plotsum(s1, n1(j), s2,n2, range, xrange); |
|
|
271 |
[legendtext,legendstyle]=legendsum(n1(j),n2,s1label,s2label,externalLegend); |
|
|
272 |
case 'sumerror' |
|
|
273 |
plotsumerror(s1, n1(j), s2,n2, range, xrange); |
|
|
274 |
[legendtext,legendstyle]=legendsumerror(n1(j),n2,s1label,s2label,externalLegend); |
|
|
275 |
end |
|
|
276 |
|
|
|
277 |
if externalLegend |
|
|
278 |
title([titlestr ' (' s1label ' ' int2str(n1(j)) ')']); |
|
|
279 |
else |
|
|
280 |
legend(char(legendtext)); |
|
|
281 |
if (~isempty(titlestr)) |
|
|
282 |
title(titlestr); |
|
|
283 |
end |
|
|
284 |
end |
|
|
285 |
end |
|
|
286 |
|
|
|
287 |
if (externalLegend) |
|
|
288 |
subplot(rows, columns, numSignals+1); |
|
|
289 |
legendsize = size(legendtext, 2); |
|
|
290 |
hold on; |
|
|
291 |
for i=1:legendsize |
|
|
292 |
plot([0 1],[legendsize-i legendsize-i], char(legendstyle(i))); |
|
|
293 |
text(1.5, legendsize-i, char(legendtext(i))); |
|
|
294 |
end |
|
|
295 |
hold off; |
|
|
296 |
axis([0 6 -1 legendsize]); |
|
|
297 |
axis off; |
|
|
298 |
end |
|
|
299 |
|
|
|
300 |
|
|
|
301 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
302 |
end |
|
|
303 |
|
|
|
304 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
305 |
function plotcompare(s1, n1, s2, n2, range, xrange); |
|
|
306 |
style=getStyles; |
|
|
307 |
K = regress(s1(n1,:)',s2'); |
|
|
308 |
plot(xrange, s1(n1,range), char(style(1))); |
|
|
309 |
hold on |
|
|
310 |
for i=1:size(n2,2) |
|
|
311 |
plotstyle=char(style(i+1)); |
|
|
312 |
plot(xrange, K(n2(i))*s2(n2(i),range), plotstyle); |
|
|
313 |
end |
|
|
314 |
hold off |
|
|
315 |
|
|
|
316 |
function [legendText, legendStyle]=legendcompare(n1, n2, s1l, s2l, externalLegend); |
|
|
317 |
style=getStyles; |
|
|
318 |
if (externalLegend) |
|
|
319 |
legendText(1)={[s1l ' (see the titles)']}; |
|
|
320 |
else |
|
|
321 |
legendText(1)={[s1l ' ', int2str(n1)]}; |
|
|
322 |
end |
|
|
323 |
legendStyle(1)=style(1); |
|
|
324 |
for i=1:size(n2, 2) |
|
|
325 |
legendText(i+1) = {[s2l ' ' int2str(n2(i))]}; |
|
|
326 |
legendStyle(i+1) = style(i+1); |
|
|
327 |
end |
|
|
328 |
|
|
|
329 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
330 |
function plotsum(s1, n1, s2, n2, range, xrange); |
|
|
331 |
K = diag(regress(s1(n1,:)',s2')); |
|
|
332 |
sigsum = sum(K(:,n2)*s2(n2,:)); |
|
|
333 |
plot(xrange, s1(n1, range),'k-', ... |
|
|
334 |
xrange, sigsum(range), 'b-'); |
|
|
335 |
|
|
|
336 |
function [legendText, legendStyle]=legendsum(n1, n2, s1l, s2l, externalLegend); |
|
|
337 |
if (externalLegend) |
|
|
338 |
legendText(1)={[s1l ' (see the titles)']}; |
|
|
339 |
else |
|
|
340 |
legendText(1)={[s1l ' ', int2str(n1)]}; |
|
|
341 |
end |
|
|
342 |
legendText(2)={['Sum of ' s2l ': ', int2str(n2)]}; |
|
|
343 |
legendStyle={'k-';'b-'}; |
|
|
344 |
|
|
|
345 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
346 |
function plotsumerror(s1, n1, s2, n2, range, xrange); |
|
|
347 |
K = diag(regress(s1(n1,:)',s2')); |
|
|
348 |
sigsum = sum(K(:,n2)*s2(n2,:)); |
|
|
349 |
plot(xrange, s1(n1, range),'k-', ... |
|
|
350 |
xrange, sigsum(range), 'b-', ... |
|
|
351 |
xrange, s1(n1, range)-sigsum(range), 'r-'); |
|
|
352 |
|
|
|
353 |
function [legendText, legendStyle]=legendsumerror(n1, n2, s1l, s2l, externalLegend); |
|
|
354 |
if (externalLegend) |
|
|
355 |
legendText(1)={[s1l ' (see the titles)']}; |
|
|
356 |
else |
|
|
357 |
legendText(1)={[s1l ' ', int2str(n1)]}; |
|
|
358 |
end |
|
|
359 |
legendText(2)={['Sum of ' s2l ': ', int2str(n2)]}; |
|
|
360 |
legendText(3)={'"Error"'}; |
|
|
361 |
legendStyle={'k-';'b-';'r-'}; |
|
|
362 |
|
|
|
363 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
364 |
function style=getStyles; |
|
|
365 |
color = {'k','r','g','b','m','c','y'}; |
|
|
366 |
line = {'-',':','-.','--'}; |
|
|
367 |
for i = 0:size(line,2)-1 |
|
|
368 |
for j = 1:size(color, 2) |
|
|
369 |
style(j + i*size(color, 2)) = strcat(color(j), line(i+1)); |
|
|
370 |
end |
|
|
371 |
end |
|
|
372 |
|
|
|
373 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
374 |
function range=chkrange(r, s) |
|
|
375 |
if r == 0 |
|
|
376 |
range = 1:size(s, 2); |
|
|
377 |
else |
|
|
378 |
range = r; |
|
|
379 |
end |
|
|
380 |
|
|
|
381 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
382 |
function xrange=chkxrange(xr,r); |
|
|
383 |
if xr == 0 |
|
|
384 |
xrange = r; |
|
|
385 |
elseif size(xr, 2) == 2 |
|
|
386 |
xrange = xr(1):(xr(2)-xr(1))/(size(r,2)-1):xr(2); |
|
|
387 |
elseif size(xr, 2)~=size(r, 2) |
|
|
388 |
error('Xrange and range have different sizes.'); |
|
|
389 |
else |
|
|
390 |
xrange = xr; |
|
|
391 |
end |
|
|
392 |
|
|
|
393 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
394 |
function n=chkn(n,s) |
|
|
395 |
if n == 0 |
|
|
396 |
n = 1:size(s, 1); |
|
|
397 |
end |