Plot 2D topographic map of EEG node network on MATLAB - matlab

I would like to plot a topographic map from EEG network. The electrodes (nodes) have a associated networks metric and from these values I want to interpolate between them and plot in a head shape. Here is the code that i have reseached and the result that I am getting...
=========================================
%The position X and Y as integers (electrodes position) and the value of Z (network metric)
X = [36 51 66 11 22 51 79 91 3 16 51 86 99 1 14 51 88 101 3 16 51 86 99 11 22 51 79 91 36 51 66];
Y = [99 101 99 80 85 87 85 80 66 69 70 69 66 51 51 51 51 51 36 33 32 33 36 22 17 15 17 22 3 1 3];
Z = [-404 -566 -379 -71 -102 -119 -87 9 -62 -160 -104 -81 -26 12 -120 -176 -85 -13 0 -118 -288 -159 -36 -115 -145 -292 -215 -266 -235 -364 -192];
%Making the meshgrid
for dd = 1:31
I(Xd(dd),Yd(dd))=Zd(dd);
end
Zd = [Zd; zeros(70,1)];
Xd = [Xd; zeros(70,1)];
Yd = [Yd; zeros(70,1)];
[XX,YY] = meshgrid(1:101,1:101);
z = griddata(Xd,Yd,Zd,XX,YY,'cubic');
contourf(z)
=========================================
The resulting plot of this code is
http://s16.postimg.org/s7a627s5h/Graph.jpg
I would like some help to remove this "tail" from my graph and a sugggestion of how to draw a head + nose on the same picture (only if it is possible to plot this kind of graph).

I don't have enough reputation to comment above but you can set your own custom locations in EEGlab as far as I remember. Have you looked at the function writelocs? Maybe that helps. EEGlab's topoplots include nose and ears.
http://sccn.ucsd.edu/eeglab/allfunctions/writelocs.html

Related

plot coordinate text file for regionprop usage - Matlab

Based on a previous question (read coordinate text file for regionprop usage - Matlab) I wish to plot the object with an extended boundaries (zeros+10) but it does not work. Any reason why?
Code:
clc;
clear;
filename = fullfile('E:/outline.txt');
fileID = fopen(filename);
C = textscan(fileID,'%d %d');
fclose(fileID);
xMax = double(max(C{1})-10)
yMax = double(max(C{2})+10)
bw=roipoly(zeros(xMax ,yMax ),C{1},C{2});
imshow(bw);
stats = regionprops(bw);
coordinate text file content is as follow:
88 10
87 11
87 12
88 13
88 14
92 21
93 22
93 23
94 24
95 25
100 33
101 34
102 34
103 34
103 33
103 32
103 31
103 30
103 29
103 28
103 27
102 26
102 25
101 24
101 23
100 22
100 21
100 20
99 19
99 18
94 12
93 12
92 12
91 11
90 11
xMax = double(max(C{1})-10)
That should probably be +10. This way you make the image smaller than your polygon.
If you want to extend the image on the left side also, add an offset to your polygon coordinates:
bw = roipoly(zeros(yMax, xMax), C{1}+5, C{2}+5);
Note also that I swapped xMax and yMax from your code, this might be another issue you're seeing. Matrix dimensions are specified as (height, width), as are indices into the matrix. But some functions such as roipoly take coordinates with x first and y second. This is a common pitfall with MATLAB syntax.
I just learned that the above is the same as
bw = roipoly(yMax, xMax, C{1}+5, C{2}+5);

read coordinate text file for regionprop usage - Matlab

I have a coordinate text file and I wish to read it into a regionprop. I wish to use the regionprop for few analysis like Centroid. How can I do it?
Code:
filename = fullfile('E:/outline.txt');
fileID = fopen(filename);
C = textscan(fileID,'%d %d');
fclose(fileID);
stats = regionprops(C,'Centroid')
coordinate text file content is as follow:
88 10
87 11
87 12
88 13
88 14
92 21
93 22
93 23
94 24
95 25
100 33
101 34
102 34
103 34
103 33
103 32
103 31
103 30
103 29
103 28
103 27
102 26
102 25
101 24
101 23
100 22
100 21
100 20
99 19
99 18
94 12
93 12
92 12
91 11
90 11
89 10
88 10
Why don't you just use centroid, which was introduced in 2017b?
[x,y] = centroid(C);
If you are insistent on regionprops (which is slower, and less accurate than operating on the polygon directly) then you are misunderstanding how region props works. Region props works on images. You need to first create an image, then pass the image to region props.
bw = roipoly(zeros(120), C(:,1), C(:,2));
stats = regionprops(bw);
You can find roipoly useful: this allows you to convert a list of 2d points/polygon vertices into a binary mask.
The resulting binary mask can then be fed to regionprops

Color code points of 3D scatter plot according to density of points

I have a 3D scatter plot of points in the xyz-sphere. I was wondering if there is a way to colormap/hue the scatter plot based on the density of the data. Basically, the parts of the scatter plot with the most densely clustered data points would be dark red, semi densely clustered data points would be medium red, and sparsely clustered data points would be light red.
This is the way that I was thinking of, but (hopefully) there might be a simpler function or command to do this.
Set a threshold that a data point in the scatter has to be surrounded by:
[ >= 10 other points within a sphere of radius 1 to be colored dark red,
[ 5-9 other points within a sphere of radius 1 to be colored medium red, and
[ 0-4 within a sphere of radius 1 to be colored light red.
Of course, I'm hoping there is a simpler way to do this that involves more than 3 colors in the color map, so if anyone has any ideas how to code this, I'd appreciate the help! Thank you so much.
Here's a snippet of my array:
184 115 3915
185 115 3916
185 115 1205
186 115 4094
187 115 2237
192 115 1519
193 115 1327
201 115 1170
240 115 2946
241 115 1332
54 116 1244
58 116 3650
59 116 3984
60 116 1631
61 116 1198
61 116 1194
62 116 1189
65 116 1185
186 116 3669
188 116 3986
189 116 2027
197 116 1200
201 116 1254
226 116 3752
227 116 1457
242 116 1405
54 117 1191
54 117 1305
56 117 1177
58 117 1169
61 117 1367
62 117 1428
62 117 1434
62 117 1435
63 117 1422
198 117 1197
229 117 1312
230 117 1179
243 117 1272
55 118 1236
56 118 1166
61 118 1191
65 118 1755
57 119 1213
57 119 1176
58 119 1253
62 119 1365
62 119 1331
63 119 1457
63 119 1251
66 119 1842
66 119 1468
59 120 1489
59 120 1387
60 120 1218
60 120 1224
61 120 1214
61 120 1440
62 120 1198
64 120 1240
205 120 3601
205 120 1168
206 120 3727
207 120 4089
208 120 2128
208 120 1160
56 121 1293
57 121 1183
59 121 1371
59 121 1347
61 121 1314
64 121 1346
207 121 3562
208 121 3845
209 121 3534
210 121 1201
210 121 1405
83 122 1794
206 122 1259
207 122 1161
83 123 3550
In my approach I'm using a threshold factor T to determine how many other points are considered in the calculation of distances for each individual point. T = 1 means for every point the average distance to all other points is calculated, T = 0.01 means for every point the average distance to the closest 1% of the the other points is calculated.
figure
%// example data
[X,Y,Z] = sphere(15);
x = [0.1*X(:); 0.4*X(:); 0.7*X(:)];
y = [0.2*Y(:); 0.5*Y(:); 0.8*Y(:)];
z = [0.3*Z(:); 0.6*Z(:); 0.9*Z(:)];
D = [x(:), y(:), z(:)];
N = numel(x);
%// calculation of color vector
[n,m] = ndgrid(1:N,1:N);
%// euclidian distance of each point to every other point
X = arrayfun(#(a,b) sum( (D(a,:) - D(b,:)).^2 ), n, m);
%% subplot 1
%// threshold factor
T = 0.01;
%// sort distances of points
Y = sort(X,2);
%// calculate average distance of the closest T% of all points
Z = mean(Y(:,2:ceil(N*T)),2);
%// plot
subplot(121)
scatter3(x,y,z,20,Z,'filled');
title('T = 0.01')
colormap
colorbar
%% subplot 2
%// threshold factor
T = 1;
Y = sort(X,2);
Z = mean(Y(:,2:ceil(N*T)),2);
%// plot
subplot(122)
scatter3(x,y,z,20,Z,'filled');
title('T = 1')
colormap
colorbar
This is a pretty crude function, but I think it achieves a similar result to what you want.
Loop through each point, calculate the number of points within some tolerance distance.
Plot these points, using the count of nearby points as a scaling for the colour.
Code:
a = rand(1000,3); % Create random matrix, use your data here
n = zeros(size(a,1),1); % Set up array for number of nearby points
tol = 0.2; % Tolerance for (squared) distance to count as "nearby"
sz = size(a,1); % Shorthand for size of data
% Loop over every point
for ii = 1:sz;
dists = sum((repmat(a(ii,:), sz, 1) - a).^2, 2); % Get standard Euclidean distance
n(ii) = nnz(dists < tol); % Count number of points within tolerance
end
% Plot, colouring by an nx3 RGB array, in this case just
% scaling the red and having no green or blue.
scatter3(a(:,1), a(:,2), a(:,3), [], [n./max(n), zeros(numel(n),2)], 'filled');
grid on;
Output:

Matlab: 3D Surface Plot of values from own vectors

I have 3 vectors with values for coordinates (X,Y,Z) and I want to plot them as a surface. I have tried all sorts of solutions from here and other forums and cannot for the life of me get it to look like anything that makes sense. I have a picture that can describe the situation better but I can't post it as I don't have enough reputation. Please help. Thank you.
EDIT: This is the link to the picture :
In the picture, the origin of each vector arrow represents the point in a 3D coordinate, with the length of the vector arrow giving the magnitude of the required torque to move at that point in 3D space.
Right now, the data is separated in line vectors with each point's coordinate: so that's one vector for the X, one for Y. Z is one line inside a 3 line matrix as the whole matrix describes the required torque in a 3 coordinate axes.
I've tried using meshgridon the X and Y vectors and then attributed the Z value using griddataand then surfbut I'm not getting something that looks like the original:
The plot is linear but I'm pretty sure the data is not... at least not that linear.
It seems like you want want to plot the single points decribed by the vectors, here you have an old answer of mine (as a bonus you will have nice colorful plots 'cause that's what the original question asked):
Assuming Data=[Vec1,Vec2,Vec3,...] and VecN=[Xn,Yn,Zn]'
"
If you want to plot points, you can define an RGB color and plot single points with hold on like this:
hold on
for i=1:length(Data(:,1))
plot3(Data(i,1),Data(i,2),Data(i,3),'Color',[(i/100*255)/255 0/255 (255-(i/100*255))/255],'LineWidth',2)
end
shg
"
Managed to solve the problem. As mentioned, the data was not uniform and because of that, surfwas jumping from one end of the plot to the other, creating a total mess. Solved it by organising the values linearly using linspaceand then using those values to create the meshgrid and then assign the Z values using griddata with a cubic interpolation.. Managed to produce proper looking surface plots with the data on hand.
Plot each data point separately within a loop:
figure; hold on; grid on;
for i = 1:length(x)
stem3(x(i),y(i),z(i));
end
Don't forget to add hold on. Use "Rotate 3D" button from the toolbar in the figure window if the plot was shown in 2D at first.
You can use griddata parameter to natural, cubic or v4. This will do interpolation and make your graph with non-uniform data smooth
Below is a sample MATLAb code
x=[32 20 67 1 98 34 57 65 24 82 47 55 8 51 13 14 18 30 37 39 10 33 21 26 38 81 83 60 95 22 17 5 72 46 99 52 12 25 96 29 70 85 43 69 19 78 97 31 89 53 2 91 48 71 61 15 36 84 94 50 11 80 6 7 49 74 9 88 40 79 27 68 73 64 63 59 86 23 35 58 45 28 100 42 93 87 16 90 41 66 54 92 77 4 62 76 75 56 3 44];
y=[96 75 24 9 83 49 27 77 3 23 17 31 40 13 7 52 51 21 98 47 64 79 78 91 44 16 15 100 84 99 63 68 70 30 54 76 97 73 33 5 88 8 71 66 62 25 60 42 72 45 18 11 28 59 89 65 10 55 69 81 12 26 20 95 87 41 74 50 93 22 43 90 14 34 82 35 56 38 80 32 1 57 6 36 37 61 29 58 2 48 4 46 67 53 92 86 94 19 39 85];
z=[55 31 11 45 83 36 86 49 15 57 42 46 8 94 88 47 54 81 98 41 32 35 56 85 9 89 37 60 23 62 67 100 78 76 73 80 10 20 68 34 77 93 1 63 53 12 22 99 91 40 84 24 33 3 43 19 92 97 6 82 64 25 26 79 95 4 44 58 5 21 70 29 65 87 96 90 51 14 18 2 72 28 71 39 52 7 27 59 50 61 48 30 66 69 17 13 74 16 75 38];
xlin = linspace(min(x), max(x), 100);
ylin = linspace(min(y), max(y), 100);
[X,Y] = meshgrid(xlin, ylin);
% Z = griddata(x,y,z,X,Y,'natural');
% Z = griddata(x,y,z,X,Y,'cubic');
Z = griddata(x,y,z,X,Y,'v4');
mesh(X,Y,Z)
axis tight; hold on
plot3(x,y,z,'.','MarkerSize',15)

Sliding window algorithm for activity recognition

I want to write a sliding window algorithm for use in activity recognition.
The training data is <1xN> so I'm thinking I just need to take (say window_size=3) the window_size of data and train that. I also later want to use this algorithm on a matrix
.
I'm new to matlab so i need any advice/directions on how to implement this correctly.
The short answer:
%# nx = length(x)
%# nwind = window_size
idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix(nx/nwind)-1))*nwind)-1;
idx will be a matrix of size nwind-by-K where K is the number of sliding windows (ie each column contains the indices of one sliding window).
Note that in the code above, if the last window's length is less than the desired one, it is dropped. Also the sliding windows are non-overlapping.
An example to illustrate:
%# lets create a sin signal
t = linspace(0,1,200);
x = sin(2*pi*5*t);
%# compute indices
nx = length(x);
nwind = 8;
idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix(nx/nwind)-1))*nwind)-1;
%'# loop over sliding windows
for k=1:size(idx,2)
slidingWindow = x( idx(:,k) );
%# do something with it ..
end
%# or more concisely as
slidingWindows = x(idx);
EDIT:
For overlapping windows, let:
noverlap = number of overlapping elements
then the above is simply changed to:
idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix((nx-noverlap)/(nwind-noverlap))-1))*(nwind-noverlap))-1;
An example to show the result:
>> nx = 100; nwind = 10; noverlap = 2;
>> idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix((nx-noverlap)/(nwind-noverlap))-1))*(nwind-noverlap))-1
idx =
1 9 17 25 33 41 49 57 65 73 81 89
2 10 18 26 34 42 50 58 66 74 82 90
3 11 19 27 35 43 51 59 67 75 83 91
4 12 20 28 36 44 52 60 68 76 84 92
5 13 21 29 37 45 53 61 69 77 85 93
6 14 22 30 38 46 54 62 70 78 86 94
7 15 23 31 39 47 55 63 71 79 87 95
8 16 24 32 40 48 56 64 72 80 88 96
9 17 25 33 41 49 57 65 73 81 89 97
10 18 26 34 42 50 58 66 74 82 90 98