Interpolating from one grid to another

Hello experts
Please, could someone help me with an interpolation?
I have two different 2D scattered grids (X = longitude, Y = depth), and a variable temperature, from two different datasets. On the first one x and y are 41x37, and on the second 24x10. Also Temp1 (41x37) and Temp2 (24x10).
I need to compute the difference (Temp1 - Temp2), but for that, I need Temp2 to be on the same format (and coordenates) as Temp1, that is, 41x37. Then, I guess I have to interpolate X2, Y2, Temp2, to the coordinates of X1, Y1.
I tried scatteredInterpolant function, but I it doesn't work, moreover, it does not allow me to inform the reference coordinates, that is, X1,Y1.
Both scatteredInterpolant and TriScatteredInterp has the structure F = function(x,y,v), but I need something like NewTemp2 = function(X1,Y1,X2,Y2,Temp2).
Please, could someone help me with this?
The data is attached, thank you very much in advance!

 Risposta accettata

It appears that ‘Temp1’ seems to not have made it to the save function argument llist.
This interpolates ‘Temp2’ to the (X1,Y1) grids using scatteredInterpolant
load('data.mat')
whos
Name Size Bytes Class Attributes Temp2 24x10 1920 double X1 41x37 12136 double X2 24x10 1920 double Y1 41x37 12136 double Y2 24x10 1920 double ans 1x32 64 char cmdout 1x33 66 char gdsCacheDir 1x14 28 char gdsCacheFlag 1x1 8 double i 0x0 0 double managers 1x0 0 cell managersMap 0x1 8 containers.Map
figure
surfc(X2, Y2, Temp2)
grid on
xlabel('X2')
ylabel('Y2')
zlabel('Temp2')
X2Y2 = [X2(:), Y2(:)];
X2Y2(isinf(X2Y2)) = NaN;
X2Y2 = fillmissing(X2Y2, 'linear');
X2v = X2Y2(:,1);
Y2v = X2Y2(:,2);
FTemp2 = scatteredInterpolant(X2v(:), Y2v(:), Temp2(:));
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
Temp2i = FTemp2(X1, Y1);
figure
surfc(X1, Y1, Temp2i)
grid on
xlabel('X1')
ylabel('Y1')
zlabel('Temp2 — Interpolated To (‘X1,Y1’)')
Do the same sort of approach to interpolate ‘Temp1’ to the ‘Temp2’ grids, if necessary.
EDIT — Corrected typographical errors.
.

13 Commenti

Hey Star Strider,
I didn't include Temp1 because for the purpose of the question it wasn't needed.
This worked perfectly!
Now I can compute the difference between Temp1 and 2. I know how to do it.
Thank you very much, have a good weekend!
As always, my pleasure!
You have a good weekend, too!
Hey experts,
This method above to interpolate is creating artifacts on the data. For example on the attached image (nitrate vertical section of water column from the coast to offshore), it is possible to see the vertical interpolation is messing with the vertical patterns of nitrate distribution (those vertically elongated lines within the red circle). I think it would be necessary to interpolate with the cubic method, or even other method, to consider both, data below and on the side when computing the interpolation. Searching I found that maybe griddata would be a good option, since it contain the cubic method among the options, but I couldn't figure it out. For example, I need to fill missing values that are represented as NaNs, but the method doesn't allow for NaNs. Please, could you help me with this? Or even other solution you consider easier or most appropriate. Thank you very much!
You can certainly use griddata, however I am not getting good results with it using the available data using either the 'linear', 'cubic' or 'natural' interpolation methods —
load('data.mat')
whos -file data.mat
Name Size Bytes Class Attributes Temp2 24x10 1920 double X1 41x37 12136 double X2 24x10 1920 double Y1 41x37 12136 double Y2 24x10 1920 double
figure
surfc(X2, Y2, Temp2)
grid on
xlabel('X2')
ylabel('Y2')
zlabel('Temp2')
X2Y2 = [X2(:), Y2(:)];
X2Y2(isinf(X2Y2)) = NaN;
X2Y2 = fillmissing(X2Y2, 'makima');
X2v = X2Y2(:,1);
Y2v = X2Y2(:,2);
FTemp2 = scatteredInterpolant(X2v(:), Y2v(:), Temp2(:), 'linear');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
Temp2i = FTemp2(X1, Y1);
figure
surfc(X1, Y1, Temp2i)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Temp2 — Interpolated To (‘X1,Y1’)')
title('scatteredInterpolant (linear)')
FTemp2 = scatteredInterpolant(X2v(:), Y2v(:), Temp2(:), 'natural');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
Temp2i = FTemp2(X1, Y1);
figure
surfc(X1, Y1, Temp2i)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Temp2 — Interpolated To (‘X1,Y1’)')
title('scatteredInterpolant (natural)')
Temp2i = griddata(X2v(:), Y2v(:), Temp2(:), X1, Y1, 'linear');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
figure
surf(X1, Y1, Temp2i)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Temp2 — Interpolated To (‘X1,Y1’)')
title('griddata (linear)')
Temp2i = griddata(X2v(:), Y2v(:), Temp2(:), X1, Y1, 'cubic');
Warning: Duplicate x-y data points detected: using average values for duplicate points.
figure
surf(X1, Y1, Temp2i)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Temp2 — Interpolated To (‘X1,Y1’)')
title('griddata (cubic)')
Temp2i = griddata(X2v(:), Y2v(:), Temp2(:), X1, Y1, 'natural');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
figure
surf(X1, Y1, Temp2i)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Temp2 — Interpolated To (‘X1,Y1’)')
title('griddata (natural)')
Are you using the same data as provided here, or a different data set?
Hey, thanks for helping me again!
The dataset is the same, however, I provided only temperature that day, but the image I sent today is for nitrate, that has some missing values in different positions. I think what you described here is enough to at least improve it. I'll be trying and let you know what I got. Thank you very much!
Unfurtunately the result for nitrate by griddata was worse than for temperature. The data is attached if you wanna take a look. Thank you anyway for your time!
I tried something new here, specifically using fillmissing on all three matrices (converted to vectors) and then using reshape to their original dimensions. That works reasonably well for the scatteredInterpolant results although not for the griddata results, with the last two having completely NaN elements even though none of the arguments (as far as I can tell) have any NaN values at all.
I am not certain what you want to do, however this approach may be an option —
load('data2.mat')
whos -file data2.mat
Name Size Bytes Class Attributes Nit 24x10 1920 double X1 41x37 12136 double X2 24x10 1920 double Y1 41x37 12136 double Y2 24x10 1920 double
% NrNaNX1 = nnz(isnan(X1))
% NrNaNY1 = nnz(isnan(Y1))
figure
surfc(X2, Y2, Nit)
grid on
xlabel('X2')
ylabel('Y2')
zlabel('Nit')
title('Original N_2 Data')
X2Y2Z2 = [X2(:), Y2(:) Nit(:)];
X2Y2Z2(isinf(X2Y2Z2)) = NaN;
X2Y2Z2 = fillmissing(X2Y2Z2, 'linear');
X2v = X2Y2Z2(:,1);
Y2v = X2Y2Z2(:,2);
X2r = reshape(X2Y2Z2(:,1), 24, []);
Y2r = reshape(X2Y2Z2(:,2), 24, []);
Nitr = reshape(X2Y2Z2(:,3), 24, []);
figure
surfc(X2r, Y2r, Nitr)
grid on
xlabel('X2')
ylabel('Y2')
zlabel('Nit')
title('‘fillmissing’ N_2 Data')
FNit = scatteredInterpolant(X2v(:), Y2v(:), Nitr(:), 'linear');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
Niti = FNit(X1, Y1);
figure
surf(X1, Y1, Niti)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Nit — Interpolated To (‘X1,Y1’)')
title('scatteredInterpolant (linear)')
FNit = scatteredInterpolant(X2v(:), Y2v(:), Nitr(:), 'natural');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
Niti = FNit(X1, Y1);
figure
surfc(X1, Y1, Niti)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Nit — Interpolated To (‘X1,Y1’)')
title('scatteredInterpolant (natural)')
Niti = griddata(X2v(:), Y2v(:), Nitr(:), X1, Y1, 'nearest');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
figure
surf(X1, Y1, Niti)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Nit — Interpolated To (‘X1,Y1’)')
title('griddata (linear)')
Niti = griddata(X2v(:), Y2v(:), Nitr(:), X1, Y1, 'cubic');
Warning: Duplicate x-y data points detected: using average values for duplicate points.
figure
surf(X1, Y1, Niti)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Nit — Interpolated To (‘X1,Y1’)')
title('griddata (cubic)')
Niti = griddata(X2v(:), Y2v(:), Nitr(:), X1, Y1, 'natural');
Warning: Duplicate data points have been detected and removed - corresponding values have been averaged.
figure
surf(X1, Y1, Niti)
grid on
view(0,90)
xlabel('X1')
ylabel('Y1')
zlabel('Nit — Interpolated To (‘X1,Y1’)')
title('griddata (natural)')
.
Hey, good morning, thanks for the new attempt to solve this.
What I want to do are to produce images like this below, that preserves the horizontal and vertical distribution of propresties (nitrate in this case) after interpolation. The image I sent to you yesterday was distorted because the artifacts created during the interpolation. The last way you tried also created distortion because it hided the horizontal distribution, creating a gradiente totally vertical only, leyered. The way the interpolation was did for this images below, was the way you providade first time. However, when zooming in (second image, some distortion shows-up. Even though, I think this is the best result we can get.
Thank you very much!
Whole water column:
Zomming-in for the first 1000 meters:
As always, my pleasure!
Some distortion is probably inevitable because the original data may not have the resolution needed to avoid it.
I am not certain what you are doing to get your results (probably some version of my original code), so I cannot comment on it beyond that. I get the impression that you are interpolating to a finer grid than I used. Filling in all the missing data appeared to improve the result when I ran it, however it may not with your interpolation. It did not appear to introduce any significant distortion when I ran it.
I did exactly as your first suggestion about two weeks ago, with same data and grid:
X2Y2 = [X2(:), -Y2(:)];
X2Y2(isinf(X2Y2)) = NaN;
X2Y2 = fillmissing(X2Y2, 'makima');
X2v = X2Y2(:,1);
Y2v = X2Y2(:,2);
Fnit_2 = scatteredInterpolant(X2v(:), Y2v(:), Nit(:));
nit_2i = Fnit_2(lons, zs);
nitGC2 = fillmissing(nit_2i,'linear');
nitGC2(no3GC2<0)=0;
pcolor(X1,Y1,nitGC2);
shading interp
colormap(parula(20))
caxis([5 28])
ylabel('Depth (m)','fontsize',10,'fontweight','b')
xlabel('Longitude','fontsize',10,'fontweight','b')
ylim([-1000 0])
text(-84.5,-900,'NO_3^{-}','fontsize',14,'fontweight','b');
cb = colorbar('Location','eastoutside');
set(cb,'position',[0.66 0.225 0.035 0.6])
Did you do something different when you got no significant distortion?
Maybe you cannot see the distortion when ploting the way you did. I could see only this way, and only when zooming-in.
I did only what I posted. I did not interpolate the grid (edge) lines, nor did I zoom in. (I do not know what aspects of the plot are more important than others, so I do not know what specifically to look for.) The important part of all this is that you get the information from the plot that you need.
Okay. Thank you very much, have a good day!
As always, my pleasure!
You, too!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Interpolation in Centro assistenza e File Exchange

Prodotti

Release

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by