Import coordinates from file .txt with Matlab - matlab

I need to plot some trajectories with matlab, i have the coordinates of each points in a file .txt, i work with c++ i want to plot this trajectories with Matlab to make some comparisons, this is an example of the file who contains the coordinates :
515 // this is x
317 // this is y
0 // i dont want to import this variable
511 // this is x
328 // this is y
20 // i dont want to import this variable
508
353
40
511
... etc
there is a function in Matlab that can help me to import only x and y?
file :
172
489
54460
283
469
54480
388
428
54500
476
384
54520
555
350
54540
635
325
54560
700
286
54580
760
250
54600
811
222
54620
840
192
54640
856
171
54660
871
175
54680
890
181
54700
930
170
54720
979
168
54740

You can read in all values using textscan and simply ignore every third value in the output by using the * in the format specifier.
fid = fopen('filename.txt', 'r');
data = textscan(fid, '%d\n%d\n%*d\n');
[x,y] = data{:};
fclose(fid);
Another option is to read in all data, then reshape and grab the parts you care about.
fid = fopen('filename.txt', 'r');
data = textscan(fid, '%d');
data = reshape(data{1}, 3, []);
x = data(1,:);
y = data(2,:);
fclose(fid);

Related

How can I plot heatmap of Wi-Fi signal strength in a 2-D surface?

I've my dataset as follows (for instance):
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]
Here, strength is the received signal strength in dBm, X and Y are 2-D coordinates. I want to plot the heatmap of the signal strength at all the coordinate points.
My situation is similar to this question. However, I want to plot the received signal strength and in Matlab, as shown in the attached figure (because of picture quality). A solution in Matlab is found here, however, the code given in the link does not work. The Command Window of Matlab displays HeatMap object with 0 rows and 0 columns. The available code in Matlab is as follows:
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]';
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]';
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]';
strengthPercent = 2*(strength+100)/100;
picture = imread('https://www.mathworks.com/help/examples/thingspeak/win64/CreateHeatmapOverlayImageTSExample_02.png');
[height,width,depth] = size(picture);
OverlayImage=[];
F = scatteredInterpolant(Y, X, strengthPercent,'linear');
for i = 1:height-1
for j = 1:width-1
OverlayImage(i,j) = F(i,j);
end
end
alpha = (~isnan(OverlayImage))*0.6;
imshow(picture);
hold on
OverlayImage = imshow( OverlayImage );
caxis auto
colormap( OverlayImage.Parent, jet );
colorbar( OverlayImage.Parent );
set( OverlayImage, 'AlphaData', alpha );
Any suggestions, please!
Thank you.
You can use scatteredInterpolant as in the code you showed, just pair it with surf
F = scatteredInterpolant(X(:), Y(:), strength(:));
[XD, Yd] = meshgrid( 0:10:410, 0:10:550 );
Zd = F( XD, Yd );
surf( XD, Yd, Zd, 'EdgeColor', 'interp' );
view([0,90]); % view 3D plot from above
You can change the colormap to customise the appearance.
colormap( 'hot' );
colorbar();
You should be able to reduce the FaceAlpha of the surface to lay it over an image.

How to calculate a triangular interpolation from values in coordinates in Matlab?

If I have a matrix with first and second columns related to coordinates and third one related to a value, how could I interpolate third column values creating iscurves and colorbar ranges?
M=[
342854 657145 309
342996 657287 73
343137 657428 84
342006 657145 1122
342147 657287 777
342289 657428 426
342430 657570 638
342571 657711 200
342713 657852 787
341723 657711 1141
341864 657852 555
342006 657994 1157
342147 658135 355
342289 658277 374
341299 658135 467
341440 658277 672
341582 658418 459
341723 658560 735
341864 658701 781
341016 658701 1233
341157 658842 218
341299 658984 539
341370 659054 1351];
and obtain something like the attached image
As your data is not in an uniform grid, you need to use griddata for interpolation.
[xq,yq]=meshgrid(linspace(min(M(:,1)),max(M(:,1)),100),linspace(min(M(:,2)),max(M(:,2)),100));
zq=griddata(M(:,1),M(:,2),M(:,3),xq(:),yq(:),'cubic'); %cubic for smoother results
[c,h]=contourf(xq,yq,reshape(zq,100,100));
clabel(c,h);

Bicubic interpolation beyond grid values in Matlab

Is it possible to achieve bi-cubic interpolation beyond grid values?
For example:
L = [5,10,20,25,40];
W= 1:3;
S= [50 99 787
779 795 850
803 779 388
886 753 486
849 780 598];
size1 = griddata(W,L,S,2,40,'cubic')
sizeBeyond = griddata(W,L,S,2,41,'cubic')
sizeV4 = griddata(W,L,S,2,41,'v4')
returns:
size1 = 780
sizeBeyond = NaN
sizeV4 = 721.57
What I was suggesting is, you can input the values which are extrapolated. Check the below code. But note that, as suggested by flawr, the extrapolation behave really bad.
l = [5,10,20,25,40];
w = 1:3;
li = [l 41] ;
S = [50 99 787
779 795 850
803 779 388
886 753 486
849 780 598];
[W,L] = meshgrid(w,l) ;
[Wi,Li] = meshgrid(w,li) ;
Si = interp2(W,L,S,Wi,Li,'spline') ;
size1 = griddata(W,L,S,2,40,'cubic')
sizeBeyond = griddata(Wi,Li,Si,2,41,'cubic')
sizeV4 = griddata(W,L,S,2,41,'v4')
Note: Don't use inbuilt commands like length,size etc as variables in the code, even for demonstration, it is trouble some.
Though, this is not answer, I have to post it here as for discussion.

Why doesn't the contourf function in Matlab use the highest value of the plotted data?

does anybody know why the function countourf doesn't use the color corresponding to the maximum value anywhere in the plot area?
if you try the code below, and then the command
get(h_colorbar,'YLim')
Matlab returns an upper limit which is not the highest element of the matrix (500), but a smaller number (475.9091).
As you can see from the commented lines in the code, I was able to change the upper/lower limits of the colorbar, but of course this doesn't solve the problem.
I'd like Matlab to actually use the highest values in my matrix of data; for instance, I'd like to see the point corresponding to (200,300) colored in the darkest red.
Xdata=[7 11 15 19 23 27 31 39 50 75 100 200];
Ydata=[50 100 140 150 200 300];
dataZ=[...
500 500 438 310 269 253 245 238 235 237 241 500 ...
500 414 291 259 248 244 241 239 239 250 274 500 ...
500 335 268 251 246 243 241 240 242 261 308 500 ...
500 323 264 250 245 243 241 241 243 265 319 500 ...
500 289 256 248 244 243 242 243 248 287 500 500 ...
360 264 250 245 244 243 244 247 261 376 500 500 ...
]';
% % % In matrix form
mdataZ=vec2mat(dataZ,length(Xdata));
[mXdata,mYdata]=meshgrid(Xdata,Ydata);
figure_5=figure;
set(gca,'FontName','Times New Roman', 'FontSize',16,'YColor','k')
hold on
box on
% % % set(gca,'CLim',[min(dataZ) max(dataZ)])
contourf(mXdata,mYdata,mdataZ,10)
scatter(19,140,50,'k')
h_colorbar=colorbar;
set(get(h_colorbar,'ylabel'),'string','Z','FontName','Times New Roman', 'FontSize',18)
set(h_colorbar,'FontName','Times New Roman','FontSize',16)
% % % set(h_colorbar,'YLim',[200 500],'YTick',[0:50:500])
% % % caxis([200 500])
axis([min(min(mXdata)),max(max(mXdata)),min(min(mYdata)),max(max(mYdata))])
xlabel('X','FontName','Times New Roman', 'FontSize',18)
ylabel('Y','FontName','Times New Roman', 'FontSize',18)
Any idea?
Thanks in advance!
contourf splits your data into n (10 for your case) levels. Unless you specify the levels they are chosen automatically by the function.
The highest level must be lower than the highest point in your data. Maybe it could be the same, I'm not sure how matlab treats values equal to a contour in this case. But if you leave it to automatic contour levels it will definitely be lower.
The individual data points are not plotted by the function, only the contour heights. Therefore, the value 500 is not in the colormap and the max is the height of the highest contour.
To solve this you can put a vector of contour values rather than n. Put the highest value close or equal to 500.
Following your suggestion, I replaced the line calling the countourf function.
Instead of the number of elements (10), I put linspace(min(dataZ),max(dataZ),10).
Interestingly, the minimum value used by contourf seems always to be the lowest element of the input matrix.
If you're curious, compare the previous code and the following:
new_figure=figure;
set(gca,'FontName','Times New Roman', 'FontSize',16,'YColor','k')
hold on
box on
contourf(mXdata,mYdata,mdataZ,linspace(min(dataZ),max(dataZ),10))
scatter(19,140,50,'k')
h_colorbar=colorbar;
set(get(h_colorbar,'ylabel'),'string','Z','FontName','Times New Roman', 'FontSize',18)
set(h_colorbar,'FontName','Times New Roman','FontSize',16)
axis([min(min(mXdata)),max(max(mXdata)),min(min(mYdata)),max(max(mYdata))])
xlabel('X','FontName','Times New Roman', 'FontSize',18)
ylabel('Y','FontName','Times New Roman', 'FontSize',18)

splitting data in one single row into multiple row in two column

I have a problem in MATLAB to split my data into multiple row in 2 column.
Currently I have a data of coordinate point (x,y) from classification in one single row. But I want to split them into multiple rows, so that each row only has two columns.
bBox = [289 1 609 1 289 17 369 145 273 161 289 161 561 241 577 241 577 257 689 257 641 273 673 273 641 321 673 321];
bBox data is got from boxPoint to create the bounding box for multiple object detection.
Can someone help me to split this data? I want the data to be like:
bBOX = [289 1; 609 1; 289 17; .....];
my partial code is shown as below:
[~, predictions] = svmclassify(P',label,model); % classifying each window
get_detect = predictions.*[predictions > 0.7];
[r,c,v]= find(get_detect);
for i = 1:r
bBox =cell2mat(boxPoint(r));
rectangle('Position',[bBox(1),bBox(2),64,128],'LineWidth',1, 'EdgeColor','y');
end
One solution is to write:
% Transform bBox into a column vector
bBox = bBox(:);
% Reshape n-by-1 vector bBox into two columns
bBox = [bBox(1:2:end-1),bBox(2:2:end)];
Another is:
bBox = reshape(bBox.',2,[]).'