Convert x y coordinates and z data to Matrix

I have three vectors
>> whos x y VAR1
Name Size Bytes Class Attributes
x 21242x1 679744 double
y 21242x1 679744 double
var1 21242x1 679744 double
where X and Y represent the location of the corresponding value of var1. What Im trying to do is to convert all this data to a matrix.
What I've done until now is:
a1 = 21242;
m = zeros(a1,a1).*NaN;
indexes = sub2ind([a1,a1],x,y);
m(indexes) = var1
Based on this question but I'm getting an error
Error using sub2ind (line 43)
Out of range subscript.
Which, according to another question about this error, is because I'm trying access elements which does not exist on the matrix.
Any help?
Thanks!

5 Comments

indexes = sub2ind([a1,a1],x,y)
What are the values in x and y?
By the error it seems that values in x and y exceed a1*a1
Also, you can use NaN directly
%example for 2x2
m = NaN(2,2)
m = 2×2
NaN NaN NaN NaN
They are longitude (only negative values) and latitude (only positive values). Could this cause the problem?
Thanks for the comment about NaN, I'll use that!
Yes, it could.
Negetives values are not accepted as indices in MATLAB (even 0 is not accepted for that matter)
i1=sub2ind([3 3],2,2)
i1 = 5
i2=sub2ind([3 3],-2,2)
Error using sub2ind
Out of range subscript.
Thank for the input. However, it's still not working.
I have tried to element by element with a for cycle:
for i1=1:a1
indexes = sub2ind([a1 a1], abs(x(i1)), y(i1));
i1
end
and the problem is in the element 3897:
>> x(3896:3898)
-1.0021
-0.9993
-1.0026
what's the problem with that numbers? I can not find the reason why keep failing.
Indices should also be integers as well.

Sign in to comment.

 Accepted Answer

It would help to have the actual vectors.
It may be possible to use the reshape function to create matrices from the vectors, if the vectors are from a gridded original matrix. The easiest way to determine the dimensions of the arrays is to use the unique function and look at the second output. The elements of the second output should be regularly-spaced, and that difference is one dimension to specify in the reshape call, with the other one left as the empty vector [].
Otherwise, use linspace, ndgrid and griddata to create appropriate matrices from scattered data.
.

6 Comments

The second output from the unique functions gives me a list which is not regularly-spaced, maybe there is the problem?
>> [x1,x2] = unique(x);
x2(1:100)'
Columns 1 through 15
1 2 3 4 5 6 7 9 10 11 8 14 12 13 20
Columns 16 through 30
19 15 16 17 21 22 18 23 26 24 25 34 28 32 29
Columns 31 through 45
27 30 33 35 31 36 40 37 38 42 41 39 53 44 46
Columns 46 through 60
49 43 51 45 47 54 52 50 48 55 56 57 58 60 61
Columns 61 through 75
59 62 63 74 65 68 80 66 71 70 75 64 67 69 78
Columns 76 through 90
81 72 77 76 92 104 73 83 82 84 86 79 89 100 109
Columns 91 through 100
134 87 85 88 97 98 95 94 91 101
Sadly I cannot upload the data.
Since you cannot upload the data (that do not appear to be gridded), an appropriate approach is the second option —
x = randn(150,1);
y = randn(150,1);
z = rand(150,1);
figure
stem3(x,y,z, 'Marker','none')
hold on
scatter3(x, y, z, 20, z, 'filled')
hold off
grid on
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
title('Original Data')
xv = linspace(min(x), max(x), numel(x));
yv = linspace(min(y), max(y), numel(y));
[X,Y] = ndgrid(xv, yv);
Z = griddata(x,y,z,X,Y);
figure
surfc(X, Y, Z)
grid on
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
title('Interpolated Surface')
This just uses random data. The approach will be similar for your data.
.
That was a very good aproach. But since the matrix are already really big, this create a huge matrix and make collapse my system. I going to see If I can reduce the size of the matrix to use this method. Thank you!
My pleasure!
The lengths of ‘xv’ and ‘yv’ (the third argument to linspace) can be whatever you want them to be. They can be considerably shorter.
Example —
x = randn(150,1);
y = randn(150,1);
z = rand(150,1);
figure
stem3(x,y,z, 'Marker','none')
hold on
scatter3(x, y, z, 20, z, 'filled')
hold off
grid on
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
title('Original Data')
xv = linspace(min(x), max(x), 15);
yv = linspace(min(y), max(y), 15);
[X,Y] = ndgrid(xv, yv);
Z = griddata(x,y,z,X,Y);
figure
surfc(X, Y, Z)
grid on
colormap(turbo)
xlabel('X')
ylabel('Y')
zlabel('Z')
title('Interpolated Surface')
The data are yours to work with, so make whatever accommodations you need to, in order to produce the result you want.
.
Thank you!
This was helpfull to do what I needed to do.
As always, my pleasure!

Sign in to comment.

More Answers (1)

I would use interpolation to convert to a regular grid.
scatteredInterpolant is the funtion to do this with your irregularly spaced data.
[X,Y] = meshgrid(linspace(min(x),max(x),500),linspace(min(y),max(y),500));% make 500x500 grid
f = scatteredInterpolant(x,y,var1); % set up the interpolater with your data
Grid_Var1 = f(X,Y); % Do the interpolation onto the grid set up above

Products

Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!