I have measurements from a sensor that spans a frequency sweep for 41 samples that I want to plot on a surface. The matrix dimensions are 41x100 for each variable (frequency, measured data, concentration, viability). Measured data has several cells of NaNs for each sample in different locations.
I have tried to plot the variables on a surface, but it fails to plot- potentially due to the NaN values. How can I interpolate (and potentially extrapolate) for NaN values when they are located in different rows and columns? Below is a simplified version of my data with only 2 variables and the interpolation issue. I can provide more details on the other 2 variables and the surface plot code upon request.
I have tried to use missingvalue, but because frequency is on a log scale, this provides very high values for NaNs in row 1 that I don't believe are accurate.
%Load variables
measured = [NaN NaN NaN NaN 3.1 2.2 2.6 1.5 5 5.3,
-82 -63 -50 -36 NaN NaN -15 -5 -1 -1.5,
73 73.4 69 66 49 NaN 36 30 30.4 NaN];
f= logspace(1,2,10);
f= repmat(f, 3,1);
%Identify NaNs
measured_nans = isnan(measured);
%Fill NaNs with nearby values
measured_fill = fillmissing (measured, "linear"); %Just showing what this looks like
%replace NaNs with interpolated values
measured_interp = interp1( f(measured_nans), measured(measured_nans), f(measured_nans) );
I haven't figured out a reasonable interpolation. Using interp1, I get the error:
Error using griddedInterpolant Sample points must be unique.
Error in interp1 F = griddedInterpolant(X,V(:,1),method);
Error in measured_interp = interp1(f(measured_nans), measured(measured_nans), f(measured_nans));
It looks like you want to use interp1
on each row. So, it has to be called on each row individually. The simplest way to do this is with a for loop:
%Load variables
measured = ...
[NaN NaN NaN NaN 3.1 2.2 2.6 1.5 5 5.3,
-82 -63 -50 -36 NaN NaN -15 -5 -1 -1.5,
73 73.4 69 66 49 NaN 36 30 30.4 NaN];
f=logspace(1,2,10); % Don't need to use repmat here (in this case)
%Identify NaNs
measured_nans = isnan(measured);
%Fill NaNs with nearby values
measured_fill = fillmissing (measured, "linear"); %Just showing what this looks like
%replace NaNs with interpolated values
measured_interp = measured;
for ii = 1:3
measured_interp(ii,measured_nans(ii,:)) = ...
interp1( f(~measured_nans(ii,:)), measured(ii,~measured_nans(ii,:)), f(measured_nans(ii,:)) );
end
Note: that the output will still have some NaN values. This is because you are trying to interpolate outside the known values for that row (i.e. before the start or after the end). You'll have to come up with another way to fill in those values.
Note: When inputting the known points into interp1
, make sure to use the non-nan values.