Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
XYZ Values to 2-D matrix

Subject: XYZ Values to 2-D matrix

From: Rich

Date: 17 Dec, 2009 11:14:04

Message: 1 of 5

Hi,

I have X,Y,Z values that I would like to convert to a 2-D matrix. Specifically, X is longitude, Y is latitude and Z the value of a satellite telemetry at that point and I would like to present this info on a map of the world in a GUI.

'Scatter' works very well, but the resulting plot makes the GUI a bit 'clunky', even if I only take every nth data point to cut the data down to say 50,000 data points.

'griddata' is sort of OK, but doesn't really produce the sort of plots I'm after.

I decided the best way to go would be to use the 'floor' function on all my X & Y values such that they are all integers where -180 <= X <= 179 and -90 <= Y <= 90. The X and Y values then represent the indeces of the 2-D matrix. At each index, I then calculated the mean Z value and did a plot of the resulting matrix using 'mesh'. The result looks good and doesn't slow the GUI down too much. However, I am calculating the value at each index by using a nested loop which is painfully slow.

Does anyone know how to get the XYZ data straight into a 2-D matrix without looping?

Cheers

RIch

Subject: XYZ Values to 2-D matrix

From: Thomas Clark

Date: 17 Dec, 2009 12:26:04

Message: 2 of 5

Rich,

Lets say you have a column vector of X values and a column vector of Y values ('floored' to integer values as you have done). You have a vector of Z values the same size, to match.

I'd do something like:

A = accumarray([X Y],Z);
edges{1} = -180:1:179;
edges{2} = -90:1:90;
N =([X Y],'Edges',edges);

So at each location in A, you have the accumulated sum of all the Z values which reside at that location. At each location in N, you have the number of XYZ triplets which contributed to each location in A.

% Get the mean (with an elemental . divide - not very clear in this font):
meanZ = A./N;

% NB you may have to handle the case where you've got 0 values in N. I'd suggest doing something like:
mask = (A == 0) | (N == 0);
A(mask) = NaN;
N(mask) = NaN;
meanZ = A./N;

** Health Warning ** You may not have the statistics toolbox, which contains hist3. If so, you can get a little bit creative - multiply the Y coordinate by (say) 10000, and use X*Y in the bin sorting - or, give up on X and Y and simply do the whole thing using single indexing so that you can use a 1D histogram.

Hope this helps

Tom Clark

Subject: XYZ Values to 2-D matrix

From: Rich

Date: 17 Dec, 2009 15:44:06

Message: 3 of 5

Cheers Tom,

that really did the trick. 'Accumarray' was the crux function that I was missing.

I had to pad my data set out with a dummy border and then crop it to make sure I had at least one of each latitude and longitude, but apart from that I pretty much just pasted your code in and it worked - *very* quick too!

Rich

%height of 0 confirms no geolocation data for this sample
i = find(myData.HGHT ~= 0);

%turn lat and long into indeces by flooring and adding 91, 181
%add data to give matrix a dummy border that can be removed
%this ensures we have at least 1 of each lat and long.
x = [floor(myData.LONG(i)+181); (1:1:360)'; (zeros(180,1)+361)];
y = [floor(myData.LATI(i)+91); (zeros(360,1)+181); (1:1:180)'];
z = [myData.ALL_PARA(i); zeros(540,1)];
A = accumarray([x y],z);

edges{1} = 1:1:361;
edges{2} = 1:1:181;
N = hist3([x y],'Edges',edges);

%Calc mean z value and crop off dummy border
meanZ = A./N;
meanZ = meanZ(1:360, 1:180);
        
imagesc([-180 180],[-90 90],meanZ', 'parent', ax1)

Subject: XYZ Values to 2-D matrix

From: Thomas Clark

Date: 19 Dec, 2009 15:56:03

Message: 4 of 5

Rich,

You're welcome. Accumarray is one of those really useful MATLAB functions that nobody knows about. I only found out about it recently!

Good luck with the rest of your work...

Tom


"Rich " <richard.dyer@eumetsat.int> wrote in message <hgdjk6$kdi$1@fred.mathworks.com>...
> Cheers Tom,
>
> that really did the trick. 'Accumarray' was the crux function that I was missing.
>
> I had to pad my data set out with a dummy border and then crop it to make sure I had at least one of each latitude and longitude, but apart from that I pretty much just pasted your code in and it worked - *very* quick too!
>
> Rich
>
> %height of 0 confirms no geolocation data for this sample
> i = find(myData.HGHT ~= 0);
>
> %turn lat and long into indeces by flooring and adding 91, 181
> %add data to give matrix a dummy border that can be removed
> %this ensures we have at least 1 of each lat and long.
> x = [floor(myData.LONG(i)+181); (1:1:360)'; (zeros(180,1)+361)];
> y = [floor(myData.LATI(i)+91); (zeros(360,1)+181); (1:1:180)'];
> z = [myData.ALL_PARA(i); zeros(540,1)];
> A = accumarray([x y],z);
>
> edges{1} = 1:1:361;
> edges{2} = 1:1:181;
> N = hist3([x y],'Edges',edges);
>
> %Calc mean z value and crop off dummy border
> meanZ = A./N;
> meanZ = meanZ(1:360, 1:180);
>
> imagesc([-180 180],[-90 90],meanZ', 'parent', ax1)

Subject: XYZ Values to 2-D matrix

From: Rick Magnuson

Date: 26 May, 2010 19:37:05

Message: 5 of 5

Rich,

I have a similar issue but perhaps a different scale. I have some data samples taken at various lat/longs across about a 1 square km area(so 3 vector columns if you will). I need to put them in a 2D matrix and plot their intensities. Using MATLAB 6.

How do I format the data, read it, then plot it? Thanks - I'm plugging away using the above code as a starter.

Cheers,
Rick

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us