Transform cells to matrix

I have a text file with the gas concentration of each point of the space. It looks like this:
enviroment_min(m) -0.2000 -0.2000 0.0000 (X Y Z)
enviroment_max(m) 10.2000 6.2000 2.5000 (X Y Z)
NumCells_XYZ 104 64 25
CellSizes_XYZ[m] 0.1000 0.1000 0.1000
Cell_x (first colum) Cell_y(second colum) Cell_z(third colum) Gas_concentration(fourth colum)
2 2 0 0
2 2 1 0
2 2 2 0
2 2 3 0
... ... ... ...
2 2 24 0
2 3 0 0
2 3 1 0
... ... ... ...
2 3 24 0
2 4 0 0
... ... ... ...
2 61 24 0
3 2 0 0
3 2 1 0
... ... ... ...
So I have transform the text file to matrix:
fid = fopen('file.txt','rt');
C = textscan(fid, '%f %f %f %f', 'MultipleDelimsAsOne',true);
fclose(fid);
A = cell2mat(C);
And I would like to build a 3D matrix to plot the gas concentration, but I don't know very well how to do it. Something like this:
[0 8 2;
4 5 3;
... ... ...]
where each colum is the dimension x, y or z and the value of the matrix is the gas concentration at that point.

Answers (2)

Assuming that the x, y and z are indeed integer as in your example, from 0 to Nx, Ny, Nz, then the easiest way may be:
result = accumarray(A(:, 1:3) + 1, A(:, 4)) %add 1 to coordinate as matlab indices start at 1, not 0
This assumes that no coordinate is repeated, otherwise you'll get the sum of the gas concentrations for that coordinate.
Note that x will be along the rows, y along the columns and z across the page, if you want x and y swapped:
result = accumarray(A(:, [2, 1, 3]) + 1, A(:, 4))

3 Comments

enviroment_min_x = -0.2000
enviroment_max_x = 10.2000
CellSize_X = 0.1000
enviroment_min_y = -0.2000
enviroment_max_y = 6.2000
CellSize_Y = 0.1000
enviroment_min_z = 0.0000
enviroment_max_z = 2.5000
CellSize_Z = 0.1000
Cell_x means the number of the array index, for example:
Cell_x Cell_y Cell_z Gas_concentration
3 4 0 0
x_array will be [-0.2:0.1:10.2] and Cell_x = 3 means de third index (add 1 as matlab indices start at 1, not 0) -> x_array(4) = 0.1
y_array = [-0.2:0.1:10.2] and Cell_y = 4 means y_array(5) = 0.2
z_array = [0.0:0.1:2.5] and Cell_z = 0 means z_array(1) = 0.0
So for (x,y,z) = (0.1,0.2,0.0) -> gas concentration = 0.0
I have tried this:
x = -0.2:0.1:10.1;
y = -0.2:0.1:6.1;
z = 0.0:0.1:2.4;
indices = find(A(:,4)<=1000);
A(indices,:) = []; % remove the concentrations under the limit
B(:,1) = x(A(:,1)+1);
B(:,2) = y(A(:,2)+1);
B(:,3) = z(A(:,3)+1);
B(:,4) = A(:,4);
scatter3(B(:,1),B(:,2),B(:,3),5,B(:,4),'filled')
set(gca,'XLim',[-0.2 10.2],'YLim',[-0.2 6.2],'ZLim',[0 2.5])
cb = colorbar;
I don't if there is any way to do it better.
Your way is fine, and since you understand it, you should probably keep it, although you can get rid of the find, that is:
indices = A(:,4)<=1000; %logical array instead of explicit indices
would work just the same on the next line.
I would have done it like this:
[x, y, z] = ndgrid(-0.2:0.1:10.1, -0.2:0.1:6.1, 0.0:0.1:2.4); %create 3D matrix of x, y, z cells
gas_concentration = accumarray(A(:, 1:3)+1, A(:, 4), [], [], NaN); %create matching matrix for concentration
toplot = gas_concentration <= 1000; %will only plot value less than 1000 and not NaN (since NaN is not less than 1000)
scatter3(x(toplot), y(toplot), z(toplot), gas_concentration(toplot));
%... plot formatting
Thank you very much!
S = scatteredInterpolant(A(:,1),A(:,2),A(:,3),A(:,4));
result = S(A(:,1),A(:,2),A(:,3));

1 Comment

Seems a bit of a waste to create an interpolant if all you're doing is querying it to get back the same points that you put in.
However, there is value in doing this if the gas concentration is desired at points that are not in the input file.

This question is closed.

Asked:

on 31 Jul 2019

Closed:

on 20 Aug 2021

Community Treasure Hunt

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

Start Hunting!