Plotting a fit with excluded data results in error "Subscript indices must either be real positive integers or logicals."

5 views (last 30 days)
I have fitted some data where I have excluded the first point and now would like to plot it. I'm using the command
exclude = 1;
handle = plot(fit,'b',time,data,'+k',exclude,'xr');
From that I get the error
Subscript indices must either be real positive integers or logicals.
Error in cfit/plot (line 229)
xpoints(outliers),ypoints(outliers),S3,...
Error in calcFRETDecayDelta_broken (line 558)
handle = plot(fit,'b',time,data,'+k',exclude,'xr');
Setting
exclude = 2;
or
exclude = [1 2];
or typecasting the 1 to a boolean works just fine. I'm reading the exclude vector from a textfile and would like to keep it in the index format there.
So I have now made a workaround by making the index exclude a boolean, which is also accepted by plot:
ex = zeros(max(exclude),1);
ex(exclude) = 1;
exclude = boolean(ex);
The question however is, why does plot not accept a simple 1 for exclusion? This is unnecessary cumbersome.

Accepted Answer

dpb
dpb on 14 Jun 2018
Edited: dpb on 10 Jul 2018
I can reproduce symptoms here with R2017b; appears to be a bug. I thought perhaps using the named parameter form
handle = plot(fit,'b',time,data,'+k','Exclude',exclude,'xr');
might give the parser enough of a hint but no joy there either.
For a workaround similar to yours, you can keep the index vector as the input and use
exclude=ismember([1:length(time)],exclude);
to build the logical vector on the fly; you could define a function handle to use as
fnPlot=@(f,x,y,ex) plot(f,'b',x,y,'+k',ismember([1:length(x],ex),'xr');
and then call as
h=fnPlot(fit,time,data,exclude);
But, it does appear you're right; there is a bug in the input parser of a surprising-to-find hadn't been caught nature. Report via the official TMW support site.
ADDENDUM
The bug is in
function contains = iContainsOnlyLogicalValues(exclude)
% This function has been written to check how an exclude array has been
% stored for the fit options. It checks to see whether the array contains
% only ones and zeros, and can serve as a logical array
contains = all(ismember(exclude, [0, 1]));
end
If the input is the point vector 1, then the above function returns true but the exclude variable is double instead of logical and later on that fails in the logical addressing usage.
It seems on surface a fixup would be
contains = all(ismember(exclude, [0, 1]));
contains = contains & numel(exclude)>1;
to make the one-element be converted to logical vector when the test reports a failure that doesn't occur now.
ADDENDUM/ERRATUM
I certainly thought I had tested the case before, but...the above fix fails if exclude is empty--I'd have not thought that
all(ismember(exclude, [0, 1]));
for that case would be TRUE; there certainly are no zeros or ones contained in an empty set, but it does.
Therefore, one needs more robust fix; in the short term without spending serious redesign effort I've added a specific test and just return--
contains = all(ismember(exclude, [0, 1])); % present TMW code
if isempty(exclude), return, end; % dpb patch 10Jul18
contains = contains & numel(exclude)>1; % dpb patch 14Jun18
  4 Comments
Johann Thurn
Johann Thurn on 14 Jun 2018
I tried your patch as well and it seems to work. I also only did some quick testing, but I don't think this should cause other problems if I just leave it like that. The function will now return 0, even if exclude = 1 is a boolean, but that should not matter, I think.
Thank you!!
dpb
dpb on 14 Jun 2018
That's TRUE, too...I thought of throwing in an isa() for 'numeric' class, but opted for the shorter version. Probably a cleaner fix is possible, indeed.

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB in Help Center and File Exchange

Products


Release

R2017a

Community Treasure Hunt

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

Start Hunting!