4D Heat Map within box - matlab

I have a box with dimensions x, y, z.
The temperatures taken at different locations of the box are given below.
xdata = [122 122 0 245 122 40 122 122 40 205 122 122 122 122 122];
ydata = [0 800 400 400 400 430 30 770 400 400 400 400 400 400 400];
zdata = [150 150 150 150 150 150 75 75 75 75 75 25 75 150 200];
thidata = [24 32 15 13 29 11 23 7 19 24 28 18 15];
For example when the location x,y,z is (122, 0, 150) the temperature was measured as 24.
I would like to create a 4D plot showing the temperature distribution inside the box with dimensions [0 250], [0 800], [0 300].

Related

Gradient descent always going to infinity

I've tried everything and can't figure out why my gradient descent isn't working. I've looked at numerous examples and have changed the gradient descent code multiple times. When I run the program I get a response of NaN. I then printed every iteration and saw that before I got to NaN the value was going higher and higher (or lower and lower to negative infinity). I've tried different alpha values, starting betas values, and the number of iterations and every time it doesn't work. What's going on?
Here is my code:
A = load('A2-datasets/data-build-stories.mat');
X = [ones(60,1) A.data_build_stories(:,1)];
y = A.data_build_stories(:,2);
b = gradDes(X, y);
function beta = gradDes(X,y)
alpha = 0.01;
beta = [0;0];
m = length(y);
for i = 1:1000
beta = beta - (alpha/m) * (X' * (X * beta - y));
end
end
And here is data-build-stories.mat:
770 54
677 47
428 28
410 38
371 29
504 38
1136 80
695 52
551 45
550 40
568 49
504 33
560 50
512 40
448 31
538 40
410 27
409 31
504 35
777 57
496 31
386 26
530 39
360 25
355 23
1250 102
802 72
741 57
739 54
650 56
592 45
577 42
500 36
469 30
320 22
441 31
845 52
435 29
435 34
375 20
364 33
340 18
375 23
450 30
529 38
412 31
722 62
574 48
498 29
493 40
379 30
579 42
458 36
454 33
952 72
784 57
476 34
453 46
440 30
428 21
you are iterating through the gradient descent with a
too big alpha for your data.
try and change it:
A = load('tmp.txt');
X = [ones(60,1) A(:,1)];
y = A(:,2);
b = gradDes(X, y);
function beta = gradDes(X,y)
alpha = 0.00000001;
beta = [0;0];
m = length(y);
for i = 1:1000
beta = beta - (alpha/m) * (X' * (X * beta - y));
end
end
b =[ 0.0001 0.0719]

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);

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:

Plot 2D topographic map of EEG node network on 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

Matlab getting point coordinates

How can I get the coordinates at a specific point?
I want to get the X coordinate of the points with Y = 18.1 ; Y = 33; Y = 70
Those points need to lie on the function that I plot.
Sample Code
t = [0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180];
y = [0 5 9 19 25 32 46 65 79 90 100 115 123 141 153 159 160 171 181 185 193 200 205 211 215 220 223 222 225 224 228 231 231 228 235 234 231];
plot(t,y) , grid on
Unfortunately, you are trying to find the values of t associated with a y, and your function is not monotonic so we need to actually code up a mock linear interpolation. Note, there may be a better way, but I do not know of it right now. Try the following code where yVals are the values you want an associated t for, and possArray will include all values of t that may satisfy those conditions.
clc; close all; clear all;
t = [0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180];
y = [0 5 9 19 25 32 46 65 79 90 100 115 123 141 153 159 160 171 181 185 193 200 205 211 215 220 223 222 225 224 228 231 231 228 235 234 231];
plot(t,y)
grid on
hold on
yVals = [18.1,33,70,222.5,230];
possArray = cell(1,numel(yVals));
iter = 1;
for val = yVals;
poss = [];
possNum = 1;
for i = 1:numel(y)-1
if y(i) <= val && y(i+1) >= val
minDiff = val-y(i);
yDiff = y(i+1)-y(i);
percAlong = minDiff/yDiff;
poss(possNum) = (t(i+1)-t(i))*percAlong+t(i);
possNum = possNum+1;
end
end
possArray{iter} = poss;
iter = iter + 1;
end
colors = hsv(numel(yVals));
legendCell = cell(numel(yVals)+1,1);
legendCell{1} = 'Original Line';
for i = 1:numel(yVals)
plot(possArray{i},yVals(i)*ones(size(possArray{i})),...
'x','MarkerSize',10,'LineWidth',2,'Color',colors(i,:))
legendCell{i+1} = ['Values for Y = ' ,num2str(yVals(i))];
end
legend(legendCell)
hold off
As stated previously, this is linear interpolation, so if you need it to be more complicated that is on you, the concept should however be similar
UPDATE
Updated code above to be a little more clean, and added a plot indicating that multiple possibilities may arise for a single value, and that the code will return all possibilities.