Interpolating by latitude and depth

조회 수: 6 (최근 30일)
Lavenia
Lavenia 2024년 2월 3일
댓글: Walter Roberson 2024년 2월 4일
I am very new to Matlab - coming from an R background and i could use some help getting started.
We sampled at numerous 'stations' along a latitudinal gradient. At each station, we collected samples from 10-20 depths. So i have a dataset that has latitude, longitude, station number, depth, and a whole range of variables (nutrients etc.).
I need to do a 2D interpolation of the data. 1) To interpolate the nutrient data from the surface to 4000 m at 1m intervals and also 2) across the latitude -60 to -58 degrees. What i have done is:
data = readtable('mock_data.csv')
[val, q] = unique(data.nut1);
z_profile = [1:4000];
Xq = -60:0.01:-58;
if length(q) > 0
Vq = interp2(data.latitude(q), data.depth(q), data.nut1(q), Xq, z_profile);
end
But i get an error
Error using griddedInterpolant
Interpolation requires at least two sample points for each grid dimension.
Error in interp2>makegriddedinterp (line 226)
F = griddedInterpolant(varargin{:});
Error in interp2 (line 126)
F = makegriddedinterp({X, Y}, V, method,extrap);
I used the example from herehttps://au.mathworks.com/help/matlab/ref/interp2.html Vq = interp2(X,Y,V,Xq,Yq) but im wondering if this error is because i have a number of "stations' that much each be treated independently?
Ive added a mock dataset, if anyone could point me in the right direction that would be greatly appreciated!

채택된 답변

Star Strider
Star Strider 2024년 2월 3일
The scatteredInterpolant function would be best for this problem.
Try this —
T1 = readtable('mock_data.csv')
T1 = 15×5 table
Station depth Lat Nut1 Nut2 _______ _____ ___ ____ ______ 1 5 -60 2 50.41 1 10 -60 4 123.21 1 100 -60 5 171.61 3 5 -59 3 82.81 3 9 -59 6 228.01 3 20 -59 7 292.41 3 50 -59 8 364.81 3 100 -59 9 445.21 3 150 -59 10 533.61 4 2 -58 3 82.81 4 5 -58 4 123.21 4 8 -58 7 292.41 4 20 -58 8 364.81 4 50 -58 10 533.61 4 100 -58 12 734.41
FNut1 = scatteredInterpolant(T1.Lat, T1.depth, T1.Nut1);
Xq = -60:0.01:-58; % Latitude Vector
Yq = linspace(0, 150, numel(Xq)); % Depth Vector
[Lat_mtx,Dpt_mtx] = ndgrid(Xq, Yq);
Nut1_mtx = FNut1(Lat_mtx, Dpt_mtx);
figure
surfc(Lat_mtx, Dpt_mtx, Nut1_mtx)
grid on
colormap(turbo)
xlabel('Latitude (°)')
ylabel('Depth (m)')
zlabel('Nutrient 1 (mol/L)')
FNut1 = scatteredInterpolant(T1.Lat, T1.depth, T1.Nut2);
Xq = -60:0.01:-58; % Latitude Vector
Yq = linspace(0, 150, numel(Xq)); % Depth Vector
[Lat_mtx,Dpt_mtx] = ndgrid(Xq, Yq);
Nut1_mtx = FNut1(Lat_mtx, Dpt_mtx);
figure
surfc(Lat_mtx, Dpt_mtx, Nut1_mtx)
grid on
colormap(turbo)
xlabel('Latitude (°)')
ylabel('Depth (m)')
zlabel('Nutrient 2 (mol/L)')
You will have to repeat this for each nutirent (or other variable), however that is not difficult.
.
  댓글 수: 16
Lavenia
Lavenia 2024년 2월 4일
Yes, i tried that, and also linear and nearest extrapolation method from here. It does cut the bottom depths where i dont have data, but it also weirdly cuts the sides where i do have data. :( i tried adding more latitude but that didnt work either.
Star Strider
Star Strider 2024년 2월 4일
I am just guessing since I don’t have your data, however starting ‘Yq’ from 0 instead of 1 may solve that —
Yq = 0:1:4000;
instead of:
Yq = [1:1:4000];
Also, the square brackets are not necessary and can slow your code.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Walter Roberson
Walter Roberson 2024년 2월 3일
interp2() expects the first two inputs to be either vectors or 2d arrays. If they are vectors then interp2() automatically expands them into grids.
interp2() expects the third input to be a 2D array.
It is not clear what q is in your code. If it is a scalar, then you would be asking to interp2() a scalar, a scalar, and a scalar -- not something that is suitable for interpolating over.
If your q is a vector of indices or is a logical mask, then latitude(q) and depth(q) are potentially vectors, so that part potentially works. But nut(q) would have to be a vector in that circumstance, not a 2d array.
The first two parameters are effectively there to describe the "marginal" indices of the grid of data that is the third parameter.
  댓글 수: 2
Lavenia
Lavenia 2024년 2월 4일
Hi Walter,
Thanks for the help! I edited the question to give a little more clarification.
The first two inputs (latitude and depth) are vectors. The third input is the nutrient concentration which varies with depth and by latitude.
q should be a vector as it just identifying unique nutrient values and preventing duplicates - but i may be wrong in how im doing this, so any help would be great!
Walter Roberson
Walter Roberson 2024년 2월 4일
The first two inputs (latitude and depth) are vectors. The third input is the nutrient concentration which varies with depth and by latitude.
For interp2() purposes, the third input must be length(depth) by length(latitude)
%example
latitude = linspace(0,1,10);
depth = linspace(0,1,15);
nc = rand(length(depth), length(latitude));
interp2(latitude, depth, nc, [0.15], [0.73])
ans = 0.5447

댓글을 달려면 로그인하십시오.

제품


릴리스

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by