How to Interpolate scalar on new grid

Dear forum,
I have a Results.csv file which contains several data from a numerical simulation (3 columns with 200 rows):
  1. Column 1: X coordinate of the mesh/grid point;
  2. Column 2: Y coordinate of the mesh/grid point;
  3. Column 3: A scalar, let's say temperature.
I recreated the grid in Matlab version 2021b with the temperature results. Now I want to interpolate the Temperature on a finner grid. I attached a part of the code I used and the error I receive. The problem seems to be in declaring "xr" and "yr" as scatter(xr,yr) shows just a straight line. Could you please tell me what am I missing?
Thank you in advance,
Regards,
Robert
%%% Read coordinates %%%
x = Results(:,1);
y = Results(:,2);
T = Results(:,3);
[X,Y]=meshgrid(x,y);
Temp = griddata(x,y,T,X,Y,'linear')
figure;
surf(X,Y,Temp)
colormap(jet);
colorbar;
%%% Refine the existing grid %%%
xr = linspace(min(x), max(x), 1000);
yr = linspace(min(y), max(y), 1000);
[Xr,Yr] = meshgrid(xr,yr);
%%% interpolate Temp on the new grid %%%
IntTemp = interp2(X,Y,Temp,Xr,Yr)
%%% ERROR %%%
Error using griddedInterpolant
Sample points must be unique.
Error in interp2>makegriddedinterp (line 226)
F = griddedInterpolant(varargin{:});
Error in interp2 (line 134)
F = makegriddedinterp(X, Y, V, method,extrap);
Error in untitled (line 50)
int=interp2(X,Y,IntTemp,Xr,Yr);

1 Comment

As always and as the comments show, without an actual dataset it is very difficult to know how to solve a given problem. Attach the data as either a .mat file containing the needed variables or the the beginning data file.
One possibility that works in some cases is to introduce "jitter" that is sufficiently large enough so as to eliminate the duplicate values but still small enough so as to not markedly change the results. A few multiples of eps generally will remove the duplicate value warning.

Sign in to comment.

 Accepted Answer

The most likely source of the problem is that ‘x’ and ‘y’ do not have unique values, so neither will ‘X’ and ‘Y’ since they are derived from them. Using unique with both the 'stable' and 'rows' arguments with the ‘Results’ matrix may solve the problem. If not (since the individual rows may be unique even if there are non-unique values in each column), it will be necessary to decide what column should be used to determine ‘uniqueness’. The first occurrences of each value of that column (the ‘ia’ or second output of unique) can then be used to define the rows, although some rows will be missing. There may be no one correct approach to this, and it may require experimentation to see what works best.
Alternatively, the griddata function may sbe the best option here.
.

7 Comments

With respect to this Answer, I don’t have the data to work with, I don’t have any idea what the data are or what constraints might be necessary in working with them, and I don’t know what the desired result is.
Perhaps sorting the matrix before interpolating it would help (although what that dimension is would be subject to experiment), since the data appear to be in some sense periodic, or at least repeating, even if not regularly. Sorting could eliminate the ‘X’ appearances below the surface.
Thank you for the reply. I attached a .csv file with X, Y and T that I used in the previous test. Scatter(X,Y,T) looks good but when I try to create the surface/grid it doesn't seem to close with the nearest node like here or here. The data are from a simple simulation of water flow in a pipe, X and Y are coordinates so each pair (X,Y) in the csv represents the position of a node in the grid and T is velocity data extracted in each node.
Try this —
T1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/845395/Test_2%20-%20Copy.csv', 'VariableNamingRule','preserve')
T1 = 455×3 table
X coord Y coord T _______ _______ _________ 0.1 0 0.0029858 0.1 1 0.0030502 0.067 0 0.0091414 0.067 1 0.010851 -0.1 0 0.0029858 -0.1 1 0.0030502 -0.067 0 0.0091414 -0.067 1 0.010851 0.1 0.1 0.003211 0.1 0.2 0.0031093 0.1 0.3 0.0029916 0.1 0.4 0.0030935 0.1 0.5 0.0030273 0.1 0.6 0.0030579 0.1 0.7 0.0030483 0.1 0.8 0.0030501
[T1u,ia] = unique(T1{:,1:2}, 'stable','rows');
T2 = T1(ia,:)
T2 = 351×3 table
X coord Y coord T _______ _______ _________ 0.1 0 0.0029858 0.1 1 0.0030502 0.067 0 0.0091414 0.067 1 0.010851 -0.1 0 0.0029858 -0.1 1 0.0030502 -0.067 0 0.0091414 -0.067 1 0.010851 0.1 0.1 0.003211 0.1 0.2 0.0031093 0.1 0.3 0.0029916 0.1 0.4 0.0030935 0.1 0.5 0.0030273 0.1 0.6 0.0030579 0.1 0.7 0.0030483 0.1 0.8 0.0030501
figure
stem3(T2.('X coord'), T2.('Y coord'), T2.T)
hold on
scatter3(T2.('X coord'), T2.('Y coord'), T2.T, 25, T2.T, 'filled')
hold off
colormap(turbo(numel(T2.T)))
xlabel('X coord')
ylabel('Y coord')
zlabel('T')
NumEdges = fix(numel(T2.T)*0.25); % Mesh Resolution
xv = linspace(min(T2.('X coord')), max(T2.('X coord')), NumEdges);
yv = linspace(min(T2.('Y coord')), max(T2.('Y coord')), NumEdges);
[Xi,Yi] = ndgrid(xv, yv);
Zi = griddata(T2.('X coord'), T2.('Y coord'), T2.T, Xi, Yi);
figure
surfc(Xi, Yi, Zi, 'EdgeColor','k')
xlabel('X coord')
ylabel('Y coord')
zlabel('T')
colormap(turbo(numel(T2.T)))
I am not certain what the desired result is.
This uses unique to eliminate the redundant values, then griddata to do the interpolation. An alternative option would be to use accumarray to average the redundant values. That might affect the shape of the surface, however I doubt it would change it significantly.
.
Thank you very much for the help, for now this should do it in my case. I know that we should keep the topic to one subject but I was wondering, is it possible to plot "T" on a flat surface created using the X and Y coordinates? As shown in the last picture, T acts like a 3rd space component but is it possible to plot its values on a 2D surface like in the picture attached?
As always, my pleasure!
One option is to use the contour function, and another is to use the view function with surf
T1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/845395/Test_2%20-%20Copy.csv', 'VariableNamingRule','preserve')
T1 = 455×3 table
X coord Y coord T _______ _______ _________ 0.1 0 0.0029858 0.1 1 0.0030502 0.067 0 0.0091414 0.067 1 0.010851 -0.1 0 0.0029858 -0.1 1 0.0030502 -0.067 0 0.0091414 -0.067 1 0.010851 0.1 0.1 0.003211 0.1 0.2 0.0031093 0.1 0.3 0.0029916 0.1 0.4 0.0030935 0.1 0.5 0.0030273 0.1 0.6 0.0030579 0.1 0.7 0.0030483 0.1 0.8 0.0030501
[T1u,ia] = unique(T1{:,1:2}, 'stable','rows');
T2 = T1(ia,:)
T2 = 351×3 table
X coord Y coord T _______ _______ _________ 0.1 0 0.0029858 0.1 1 0.0030502 0.067 0 0.0091414 0.067 1 0.010851 -0.1 0 0.0029858 -0.1 1 0.0030502 -0.067 0 0.0091414 -0.067 1 0.010851 0.1 0.1 0.003211 0.1 0.2 0.0031093 0.1 0.3 0.0029916 0.1 0.4 0.0030935 0.1 0.5 0.0030273 0.1 0.6 0.0030579 0.1 0.7 0.0030483 0.1 0.8 0.0030501
% figure
% stem3(T2.('X coord'), T2.('Y coord'), T2.T)
% hold on
% scatter3(T2.('X coord'), T2.('Y coord'), T2.T, 25, T2.T, 'filled')
% hold off
% colormap(turbo(numel(T2.T)))
% xlabel('X coord')
% ylabel('Y coord')
% zlabel('T')
NumEdges = fix(numel(T2.T)*0.25); % Mesh Resolution
xv = linspace(min(T2.('X coord')), max(T2.('X coord')), NumEdges);
yv = linspace(min(T2.('Y coord')), max(T2.('Y coord')), NumEdges);
[Xi,Yi] = ndgrid(xv, yv);
Zi = griddata(T2.('X coord'), T2.('Y coord'), T2.T, Xi, Yi);
figure
surfc(Xi, Yi, Zi, 'EdgeColor','none')
xlabel('X coord')
ylabel('Y coord')
zlabel('T')
colormap(turbo(numel(T2.T)))
view(0,90)
figure
contourf(Xi, Yi, Zi, 'EdgeColor','none')
colormap(turbo(numel(T2.T)))
figure
contourf(Xi, Yi, Zi, 'EdgeColor','none')
colormap(turbo(numel(T2.T)))
view(30,30)
I am not certain if there is any way to simply flatten (‘squash’) the surface into 2 dimensions and produce a 3D plot. The only way I can see to do that would be to use contourf (that produces a 2D plot) and then plot it in 3D.
.
Thank you again! It looks great, that is exactly what I was looking for.
Best regards,
Robert
As always, my pleasure!
.

Sign in to comment.

More Answers (2)

Error using griddedInterpolant
Sample points must be unique.
comes from
x = Results(:,1);
y = Results(:,2);
...
[X,Y]=meshgrid(x,y);
The x and y vectors must be unique for the MATLAB interpolation functions to work; your data has repeated points.
MRobert
MRobert on 27 Dec 2021
Edited: MRobert on 27 Dec 2021
Thank you both for the interest and answers. When running:
x = Results(:,1);
y = Results(:,2);
T = Results(:,3);
[X,Y]=meshgrid(x,y);
Temp = griddata(x,y,T,X,Y,'linear')
I get the following warning:
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
> In griddata>useScatteredInterp (line 181)
In griddata (line 122)
In Test (line 24) --this line 24 is "Temp = griddata(x,y,T,X,Y,'linear')"
I don't really understand what "duplicate data points" refers to. When i create the grid some of data repeats, for example among Y axis there are different values of X for the same Y value. Even in this example when the grid of X and Y is created there are some duplicated values but when I run it I have no warning. I tried to solve it using "uniques" but it deletes way too many points and I also get array of different number of values for X and Y and I can't create the grid after.
I also attach a figure which should explain better the result I am looking for. Fig 1 shows the nodes from a coarse grid. In Fig 2 I put the scalar (its values are extracted in the nodes shown in Fig 1). Now I made a finner grid in another program, imported the coordinates in MatLab and I have the grid from Fig 3. The final results I am seeking is to interpolate Temp on this grid from Fig 3.
Thank you again,
Regards,
Robert
L.E. : If I remove view(2) from Fig. 2 and rotate the graph, the result looks like below

Categories

Find more on Graphics Object Properties in Help Center and File Exchange

Products

Release

R2021b

Community Treasure Hunt

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

Start Hunting!