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
Petr Michalek
2020년 7월 1일
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);
John D'Errico
2020년 7월 1일
@ 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.
답변 (2개)
Ashish Gudla
2015년 5월 27일
1 개 추천
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:
댓글 수: 2
Walter Roberson
2015년 5월 27일
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.
A
2015년 5월 28일
Mike Garrity
2015년 5월 27일
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
A
2015년 5월 28일
Mike Garrity
2015년 5월 28일
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?
Saurish Chakrabarty
2018년 8월 6일
편집: Saurish Chakrabarty
2018년 8월 6일
Nice answer! There might be a typo though. During initialization, the dimensions of gz got interchanged.
gz = zeros(length(gy),length(gx))
카테고리
도움말 센터 및 File Exchange에서 Surface and Mesh Plots에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!