How to I convert this to a 2d array?

I have a space delimited text file in the form of x y z and I want to create a 2d array so that I can plot the contour (using contourf) - what's the best way I can do that?
This is what the data looks like: (x y z)
23.48497963 13.19587040 60.91899872
24.03828049 13.26920033 61.01649857
24.63999939 13.42000008 60.59999847
24.76104927 13.37959957 61.06637955
18.97845078 12.31340027 61.88624954
19.23686028 12.50454998 62.81980896
19.55764008 12.43560028 61.80752945
And for the contourf function, it says that I need to format that into a 2d array (and I need to have the x and y be the indices.
I tried this:
f=fopen('68 data set.txt');
c=textscan(f,'%f %f %f','CollectOutput',true);
fclose(f);
out=accumarray(c{1}+1,c{2});
And it gave an error: "Index exceeds matrix dimensions"
Also, is it true that I would have to sort the indices for the contourf function?
Your help is greatly appreciated.

 Accepted Answer

Star Strider
Star Strider on 2 Apr 2016
Edited: per isakson on 2 Apr 2016
You can do everything with the data you have and the scatteredInterpolant function. It is a core MATLAB function, and no Toolboxes are required. I was able to do this much with the data you presented:
XYZ = [ 23.48497963 13.19587040 60.91899872
24.03828049 13.26920033 61.01649857
24.63999939 13.42000008 60.59999847
24.76104927 13.37959957 61.06637955
18.97845078 12.31340027 61.88624954
19.23686028 12.50454998 62.81980896
19.55764008 12.43560028 61.80752945];
F = scatteredInterpolant(XYZ(:,1:2), XYZ(:,3), 'linear'); % ScatteredInterpolant, Linear Interpolation
[Gx,Gy] = meshgrid(XYZ(:,1), XYZ(:,2)); % Define ‘meshgrid’ As Query Points
%
figure(1)
contourf(F(Gx,Gy)) % Create Filled Contour Plot
grid
With all our data it would likely look much better. It does create a contourf plot from your data.
I am not certain where you want to go with it from here, but this code works. I didn’t post the plot because of the small amount of data you presented. With all your data it should give you the information you want. You can generate the plot I created from this code.

10 Comments

I tried that with the full data set and it actually produced a very messy filled contour plot.
(I just figured out how I can post the whole file so maybe that will help.)
Sorry about that. Thank you.
This produces a nice looking contour plot (at least to me):
fidi = fopen('Ewen Chan 68 data set.txt','rt');
D = textscan(fidi, '%f%f%f');
X = D{1};
Y = D{2};
Z = D{3};
N = 150; % Length Of Interpolation Vectors
Xi = linspace(min(X), max(X), N);
Yi = linspace(min(Y), max(Y), N);
F = scatteredInterpolant(X, Y, Z, 'linear'); % ScatteredInterpolant, Linear Interpolation
[Gx,Gy] = meshgrid(Xi, Yi); % Define ‘meshgrid’ As Query Points
Zi = F(Gx,Gy);
figure(1)
contourf(Xi, Yi, Zi) % Create Filled Contour Plot
grid
Change ‘N’ to produce coarser of finer interpolation grids.
There are many ways to tweak the contourf function. Even if you eventually need a contourf plot, I would also experiment with mesh and surf plots (and their friends meshc and surfc) to get a better idea of what your data look like.
Is there a way for me to plot the data as-is though?
I changed N to 1000 and it gives me a bunch of data points that are negative "Z" (values for the contour) where the original data doesn't have that (because the physics of the problem tells us that we can't have negative data).
Is there a way to just make it plot the x-y-z as a 2d contourf plot?
(I did not expect that it would be this complicated.)
Thank you.
I went back and plotted your original data, looking at it from several directions. The griddata function to do the interpolation may be what you want:
fidi = fopen('Ewen Chan 68 data set.txt','rt');
D = textscan(fidi, '%f%f%f');
X = D{1};
Y = D{2};
Z = D{3};
N = 150; % Length Of Interpolation Vectors
Xi = linspace(min(X), max(X), N);
Yi = linspace(min(Y), max(Y), N);
[Gx,Gy] = meshgrid(Xi, Yi); % Define ‘meshgrid’ As Query Points
Zi = griddata(X, Y, Z, Gx, Gy, 'cubic');
figure(1)
contourf(Gx, Gy, Zi, 20) % Create Filled Contour Plot
grid
figure(2)
scatter3(X, Y, Z, '.')
grid on
view([0 90])
This actually looks a lot like the scatter3 plot in figure(2), but with the appropriate contours drawn. You may want to experiment with the contourf call to vary the colormap, number of contours, and some other tweaks.
Thank you!!!
This is exactly what I was looking for.
My pleasure.
I never realised griddata was so versatile.
@Star Strider
Does it have to go through the interpolation scheme in order for me to plot my existing data?
The reason why I am asking is because it is producing data OUTSIDE the bounds of the data that I have, so I am wondering how valid the EXtrapolation is even though it's supposed to be an INterpolation.
Thanks.
If it does not model your surface accurately, there are a number of interpolation methods that might be better, such as 'nearest', 'linear', natural, and 'v4'. I would experiment with each to see which produces the best result. I chose 'cubic' because that is usually the best for complicated curved surfaces, but it may not be ideal in your application.
With respect to the functions connecting points on the upper (with respect to ‘Y’) concave part of your surface, the problem may be in the way your data are organised. The plot functions want to ‘connect the lines’ to produce a convex outline. Even delaunay and boundary (which should produce an accurate boundary even along concave regions of your surface) colour outside your intended border. Every function I’ve experimented with wants to connect the points along the concave curvature. Even the surf and mesh plots connect that region. Your data have defeated everything I can think of to not connect that region.
You can get some idea of what the problem is by plotting:
figure(3)
plot3(X, Y, Z, '-x', 'MarkerSize',5)
grid on
% view([0 90])
Enlarging it in the plot GUI will give you some idea. The plotted lines zig-zag.
Since I have no idea how your data were collected or how they are organised, I’m not certain what to suggest. Sorting them could be an option, but I have no idea how best to do that, since I don’t know anything about your data. (You would use sortrows to sort ‘D{:}’ by one of its columns.)
Generically, the data is collected by running a series of experiments, varying two parameters (one that is shown as the x-axis, and another that isn't shown) which is how I created the surface in CAD (think along the lines of a multi-section loft, except that in reality, it isn't quite that - but something similiar to that idea - if that helps you understand where the data is coming from).
And then the surface is meshed/tessellated inside the CAD environment and the resulting text file is the export of the mesh.
Hope that helps.
So what I am hoping to get out of this is to be able to plot the data "as-is" without any interpolation or extrapolation.
Thanks.
My pleasure.
It helps a bit. When I sort your data by any one of the three columns, it doesn’t change the way MATLAB displays it. Using boundary helps somewhat, but several of the points are still connected where they shouldn’t be.
There are many undocumented features in MATLAB code, that only MathWorks knows of. At this point, I suggest that you Contact Support, submit your problem as a bug report or enhancement request, and see if MathWorks can fix it. This isn’t really an ‘extrapolation’ but the problem of MATLAB creating continuities where there are none.
Include the URL of this thread: http://www.mathworks.com/matlabcentral/answers/276683-how-to-i-convert-this-to-a-2d-array in your message to MathWorks so you don’t have to repeat yourself. Just mention that this thread fully describes your problems and my attempts to solve them.
Ask MathWorks to email me with any solution they come up with, because I’d like to know if one exists. I am out of ideas.

Sign in to comment.

More Answers (3)

Solution is here
Please check it and accept my answer if this fulling your requirements

1 Comment

Ewen Chan
Ewen Chan on 2 Apr 2016
Edited: Ewen Chan on 2 Apr 2016
Yeah, I tried that too. Couldn't make heads or tails of it because I think that my question is a LOT simpler than what you had.
And it also looks like that the code that's on that page only writes it out as separate x y z text files.
What I'm looking for is to actually generate the 2d array so that I can plot it using contourf.
Thanks.

Sign in to comment.

Kuifeng
Kuifeng on 2 Apr 2016
Maybe can try the function plot3 instead of contourf.
f=importdata('68 data set.txt'); x = f(:,1); y = f(:,2); z = f(:,3); plot3(x,y,z);

1 Comment

Unfortunately, I specifically need a contour plot (because it's going to a paper publication). Thank you for your help though.

Sign in to comment.

Ewen Chan
Ewen Chan on 2 Apr 2016
This is what the 3D surface looks like in CAD.
But I am looking for a 2D contour plot because it is going into a print publication.
Maybe this would help?
So I'm looking/hoping to be able to plot the data as-is.
Thank you.

Categories

Products

Community Treasure Hunt

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

Start Hunting!