Effacer les filtres
Effacer les filtres

Avoid nans in 2D cubic spline interpolation

10 vues (au cours des 30 derniers jours)
icylab
icylab le 24 Fév 2020
Commenté : darova le 2 Mar 2020
I have XYZ data (X and Y are the coordinates of Z values). Intermintently, the Z values have NaNs.The data is a radar line with gaps in the data (hence the NaNs) and uneven spacing between each points (see figure, blue is the existing values, orange is the NaN values). What I would like is to interpolate the non-nan values on a regular spacing and leave the nans as they are. My XYZ array is +40k rows and contains approximately +5k of NaNs, sometimes consecutive and sometimes spread out.
I am using the interparc function from John (https://uk.mathworks.com/matlabcentral/fileexchange/34874-interparc) to interpolate my points as I am working with a curved line and do not want to create a meshgrid, but I get an error message every time:
Warning: All data points with NaN as their site will be ignored.
> In chckxy (line 37)
In spline (line 53)
In interparc (line 316)
Error using chckxy (line 42)
There should be at least two data points.
I have tried to replace the NaNs by an arbitrary value (999) and make each value unique, as per (https://uk.mathworks.com/matlabcentral/answers/344604-how-to-change-duplicate-values-so-that-every-value-is-unique)
% replace nans by value
new2_dpth(isnan(new2_dpth)) = 999;
% create unique values for NaNs
a = new2_dpth;
[uvals, ~, uidx] = unique(a, 'stable');
b = a;
for K = 1 : length(uvals)
mask = uidx == K;
b(mask) = uvals(K) + (0 : nnz(mask) - 1) * 0.01;
end
I can then interpolate this and remove any value above a certain threshold, but get very strange results (see second figure).
I have also tried to remove the nan's from the interpolation using a for and if loop, but this is time consuming and does not seem to work either (see below)
f=[];
for i = 1:length(b)
if b (i) ~= -999
f = interparc (100,new2_x,new2_y,b);
else
continue
end
end
Any help would be really appreciated! Thanks.
  2 commentaires
darova
darova le 24 Fév 2020
Is this correct?
icylab
icylab le 25 Fév 2020
Hi Darova,
Thanks for your help. Yes I guess this is similar to what I need. However, I already know how to interpolate data on a regular grid. I just need this interpolation to stop before and start after the nans (and not interpolate them). I'm not sure your figure does that?

Connectez-vous pour commenter.

Réponses (1)

darova
darova le 26 Fév 2020
Here is what i tried: Created new mesh and place there NaN (red points_
clc,clear
% generate random data
x = sort(rand(1,20)*5);
y = sin(x);
z = x.^2;
ix = [2 7 12 18]; % indices of NaN's
plot3(x,y,z,'.-b')
hold on
plot3(x(ix),y(ix),z(ix),'ok')
hold off
t = [0 cumsum(sqrt(diff(x).^2+diff(y).^2+diff(z).^2))];
ti = linspace(0,t(end),15); % new mesh
[tt,in] = sort([t(ix) ti]); % sort new mesh and NaN points
[~,ii] = sort(in); % sort indices to get places of NaN
% interpolate data with mesh
xx = spline(t,x,tt);
yy = spline(t,y,tt);
zz = spline(t,z,tt);
i1 = ii(1:length(ix)); % first indices are NaN
hold on
plot3(xx,yy,zz+3,'.:r')
plot3(xx(i1),yy(i1),zz(i1)+3,'ok')
zz(i1) = nan; % place NaN in data to create breaks
plot3(xx,yy,zz+3,'-r','linewidth',2)
hold off
axis vis3d
  6 commentaires
icylab
icylab le 2 Mar 2020
Only in new2dd
darova
darova le 2 Mar 2020
Try this
zz = spline(t(~ix),new2_dd(~ix),tt); % take only number (without NaN)
I gave you incorrect example above
t = [0 cumsum(sqrt(diff(x).^2+diff(y).^2+diff(z).^2))];
Because z in your case have NaN's. You can't use it

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by