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!
采纳的回答
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 个评论
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!
更多回答(0 个)
类别
在 帮助中心 和 File Exchange 中查找有关 Interpolation 的更多信息
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!选择网站
选择网站以获取翻译的可用内容,以及查看当地活动和优惠。根据您的位置,我们建议您选择:。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
