2-D Contour plot for non-uniformly spaced data points

I have arrays data from COMSOL for a non-uniform mesh: x,y node positions and u for each node, where the nodes are refined in one area. I want to create a 2-D contour plot of this data in MatLab on an x-y graph and colors representing u. All the information have found seems to involve creating a rectangular mesh via 'meshgrid' and then letting it interpolate the data to this mesh. I'm wondering if there is a simpler way where I can just plot the raw data so I don't eliminate any values?
Any help greatly appreciated.

2 Comments

Hello,
I have the same problem. I get data from Comsol via LiveLink to Matlab. I want to create a contourf plot from x, y and U, where I have one value of U for one value of x and y. However, U is row vector 1x12792 double and the values of x and y are distributed non-uniformly, because they are coordinates of the triangle mesh nodes. I can generate a uniform mesh from x,y using [X,Y]=meshgrid(x,y), but how do I generate array from U? I guess using interpolation?
My code
model = mphload ('cylinder flow.mph');
Velocity = mpheval(model,'spf.U');
Density = mpheval(model,'spf.rho');
x = Velocity.p(1,1:end);
y = Velocity.p(2,1:end);
xindex = Velocity.t(1,1:end);
yindex = Velocity.t(2,1:end);
zindex = Velocity.t(3,1:end);
meshindex = Velocity.ve(1:end,1);
U = Velocity.d1;
rho = Density.d1;
[X,Y]=meshgrid(x,y);
figure(1) % mesh display - works fine
mphmesh(model); hold on;
figure(2) % scatter graph - works fine
scatter(x,y,U,'filled');
figure(3) % 3D trimesh graph - works fine
tri = delaunay(x,y);
trisurf(tri,x,y,U); colorbar;
figure(4) % contourf graph does not work
contourf(X,Y,U);
@ Petr Michalek:
A Irecall, there are two tools one the file exchange to do contouring of scattered data. Both are probably calledd tricontour, so either should work.

Sign in to comment.

Answers (2)

If I understand you correctly, you are trying to plot the raw data, instead of creating a regular mesh using 'meshgrid'.
You can use the 'contour' or the 'contourf' functions as explained in the documentation:
Also the 'mesh' function can take irregularly spaced vector inputs. See this for an example.

2 Comments

That documentation says,
If X or Y is irregularly spaced, then contour calculates contours using a regularly spaced contour grid, and then transforms the data to X or Y.
Contour only works when 'u' (z) is a matrix of x and y points.
"If X and Y are vectors, then length(X) must equal size(Z,2) and length(Y) must equal size(Z,1). The vectors must be strictly increasing or strictly decreasing and cannot contain any repeated values".
My data is three vectors of thousands of points, but there could be more x values at y = 0 than at y = 1 because the mesh from ComSol is not uniform. So I can't simply reshape u into a matrix without losing data. That is my issue.

Sign in to comment.

The contour commands can handle curvilinear grids, but not multi-resolution grids. So I could do this:
[theta,rad] = meshgrid(linspace(0,pi,49),linspace(1,3,49));
[x,y] = pol2cart(theta,rad);
z = peaks;
contourf(x,y,z)
To get a contour of a 2D grid which wraps around a half annulus, but the X, Y, and Z inputs are all 2D arrays.
One option is to convert your data into a triangle mesh and then use Darren Engwirda's tricontour function from the File Exchange .
Another would be to use something other than a contour. For example, if your grid is fine enough, you could just use scatter to draw colored circles at each location:
scatter(x,y,120,c,'filled')
That'll give you no interpolation at all, just the raw data.

5 Comments

I don't think that is applicable to me. My data is one-dimensional vectors of x, y and u, e.g. x(1) corresponds to y(1) which corresponds to u(1). u is the velocity at the point (x,y). I just want to create a contour plot of x and y where the color intensity represents u at each point.
Here is a plot3 graph of the data, I just want to convert height changes in u to color intensity. http://imgur.com/a/BzFcG
Looking at your picture, it looks like there's some chance that your vectors are actually samples from what's called a rectilinear grid. If that is the case, then the following approach MIGHT work.
Let's work through an example. I don't have your data, so I'll make my own.
%%Create some sample data on a rectilinear grid
[x,y] = meshgrid(6*sin(linspace(0,pi,32))-3);
z = peaks(x,y);
%%Turn it into vectors
x = x(:);
y = y(:);
z = z(:);
Now let's see if we can reconstruct the rectilinear grid. We'll find the unique X & Y values, and then see if there's a value for each combination.
gx = unique(x);
gy = unique(y);
gz = zeros(length(gx),length(gy));
counts = zeros(length(gx),length(gy)); % error checking
for i=1:length(x)
c = find(gx==x(i));
r = find(gy==y(i));
gz(r,c) = z(i);
counts(r,c) = counts(r,c) + 1;
end
disp(['Counts = ', num2str(min(counts(:))), ...
', ' num2str(max(counts(:)))]);
You can see that it didn't quite work for me because there are some counts which are not equal to 1. What happened there is that some of the X & Y values were very close to each other.
But let's take a look anyways because the results might be good enough:
contourf(gx,gy,gz)
If that doesn't work, then I think that you're stuck with one of the other approaches I mentioned.
%%Scatter approach
scatter(x,y,120,z,'filled')
%%Trimesh approach
tri = delaunay(x,y);
trisurf(tri,x,y,z)
Does that make sense?
A
A on 2 Jun 2015
Edited: A on 2 Jun 2015
The problem with this approach is that a matrix of unique x and y points has more points than the input data itself. The mesh is refined around x = 5x10^-3 so there are more y points here than at say x = 0. I guess there is no simple way to transfer this data to a contour plot without creating an array with an arbitrary number of points and interpolating the data... Thanks for your help anyway!
Nice answer! There might be a typo though. During initialization, the dimensions of gz got interchanged.
gz = zeros(length(gy),length(gx))
will any one help me for 2d contour plot with the attached data for non uniformly spaced data points ???

Sign in to comment.

Products

Asked:

A
A
on 26 May 2015

Commented:

on 1 Jul 2020

Community Treasure Hunt

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

Start Hunting!