Plot contour with "concave" XY coordinates

12 visualizzazioni (ultimi 30 giorni)
I have an array of XYZ coordinates and want to plot them using contourf, so I followed this guide:
This is the result. The red dots are a scatterplot of the XY coordinates and beyond the concave border of my data there is extrapolated garbage.
I assume this happens because of linspace, but what could I use instead? I could determine the Y border for every X and set the Z coordinate corresponding to each Y past that border to NaN, but there must be a better way.
This is the code and I have also attached the data points to this post:
close all
load(websave('myFile', ''))
xv = linspace(min(X), max(X),numel(X));
yv = linspace(min(Y), max(Y),numel(Y));
[Xm,Ym] = ndgrid(xv, yv);
Zm = griddata(X, Y, Z, Xm, Ym);
hold on
Please lend me your brain power, for mine is weak.

Risposta accettata

Cris LaPierre
Cris LaPierre il 5 Apr 2023
Modificato: Cris LaPierre il 5 Apr 2023
The interpolation employed by griddata is causing this. You could look into adjusting the method used, but I did not have much success. You have the data you want already, so if you can reshape it into a matrix, you can create the contour plot without needing to use griddata. You just need to put NaNs where you don't have data.
There is no slick function for this, so I took a brute force approach based on the fact that your X data seems to be regularly sampled, while Y and Z may vary. I used unique to find the indices of each X sampling, and used that to extract and reshape the Y and Z data from vectors into matrices. There might be better approaches to achieving the same end result.
load data.mat
[uX,ia,ic] = unique(X);
% Create X,Y, and Z matrices prepopulated with NaNs
myX = NaN(length(uX));
myY = NaN(length(uX));
myZ = NaN(length(uX));
% Fill in the matrices with the orginal values
for r = 1:length(ia)
myX(1:sum(ic==r),r) = X(ic==(r));
myY(1:sum(ic==r),r) = Y(ic==(r));
myZ(1:sum(ic==r),r) = Z(ic==(r));
% Visualize the result
hold on
hold off
  1 Commento
Dennis Weber
Dennis Weber il 6 Apr 2023
Thank you, this is just what I need. contourf seems to do some interpolation with the colors and levels itself, because this looks very similar but the individual datapoints are a lot more coarse.

Accedi per commentare.

Più risposte (1)

Bjorn Gustavsson
Bjorn Gustavsson il 5 Apr 2023
Modificato: Cris LaPierre il 5 Apr 2023
NOTE: edited so that the code runs here and displays the results CL
The problem happens because griddata (and both scatteredInterpolant and triscatteredInterp) produce a triangulation with a convex perimeter.
If you switch to use an explicit delaunay-triangulation and use tricontour instead you might evade that filling between your concave boundary and the default convex one. But that might require some handcraft-work to get right.
load data.mat
tri = delaunay(Y,X);
hold on
for i1 = 1:numel(X)
% manual identification of the concave part of the perimeter
idxConcave = [70 78 85 91 97 102 107 112 116 120 124 128 131 134];
tri3 = tri;
% if all three corners of a triangle belong to the concave perimeter
for i1 = size(tri3):-1:1
idxRM(i1) = numel(intersect(tri3(i1,:),idxConcave))==3;
% I assume that you want them gone
tri3(idxRM,:) = [];
triplot(tri3, X, Y,'r')
hold on
Here I've used the tricontour-function (contour-plot-for-scattered-data by Duane Hanselman), hopefully you can find a similar tool that make filled contours.
  1 Commento
Dennis Weber
Dennis Weber il 6 Apr 2023
Thank you for your work, but this does not look that good, which is a problem because these graphs are for my thesis.

Accedi per commentare.


Scopri di più su Contour Plots in Help Center e File Exchange




Community Treasure Hunt

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

Start Hunting!

Translated by