kakearney / boundedline-pkg

Plot line(s) with error bounds/confidence intervals/etc. in Matlab
MIT License
102 stars 25 forks source link

Handle NaNs in y in same manner as 'plot' command #1

Open alexperrone opened 8 years ago

alexperrone commented 8 years ago

There has been several discussions of handling NaNs on the Matlab toolbox page. While there are several options for handling NaNs in all cases, e.g. in x, or y, or in the patch, etc. The simplest and most typical case is to handle NaNs in y in the same manner as 'plot' command so that non-contiguous lines are supported.

Consider this plot:

x = 1:10;
y = x + rand(1, 10);
boundary = 2 * ones(1, 10);
boundedline(x, y, boundary);  % requires boundedline function to be on path

bounded

Now when we add a NaN in y, this is not supported:

y(5) = NaN;
boundedline(x, y, boundary);  % error

This is the desired behavior:

bounded-nan

This is akin to the way the 'plot' command would handle this case:

plot(x, y);  % with y(5) = NaN

plot-nan2

kakearney commented 8 years ago

okay, I've received enough feedback on this topic that I'll try to implement the behavior above. I think I'll allow for a couple different behaviors: 1) remove NaNs/Infs
2) Keep them in the line, resulting in gap, but inpaint past them in the patches 3) Create a gap in both the line and the patch

If anyone has additional behaviors they'd prefer, please post here.

okomarov commented 8 years ago

I reckon 3 should be the default.

kakearney commented 8 years ago

In the end, #1 ended up being more complicated than anticipated to add to the code without major changes, so I've implemented just 2 and 3 in the most recent update. See the new 'nan' input parameter to specify this. I've kept fill-and-smooth as the default behavior for back-compatibility purposes (since that was the behavior in more recent versions).

So far testing has gone smoothly, and I'm in the process of writing up a more in-depth discussion of this function and its new options for my blog; will post here when that's done.

alexperrone commented 8 years ago

The option 1) remove NaNs/Infs was posted on the toolbox page by Eelke Spaak, this didn't work?

To fix this, I added the following around line 313, right before the actual calls to line() and patch(): % remove nans for k = 1:numel(xp) naninds = isnan(xp{k}) | isnan(yp{k}); xp{k} = xp{k}(~naninds); yp{k} = yp{k}(~naninds); end

Since it connects the points which were NaN, it basically linearly interpolates.

kakearney commented 8 years ago

Removing from just the patches would be pretty straightforward, but somewhat redundant because the results are almost identical to the 'fill' option, which simply uses a slight smoother interpolant to fill the point rather than the linear one the graphics fill in. I was worried that users would interpret "remove" to also apply to the line, and that would make coding a bit more complicated. But I've gone ahead and added the remove-from-patches-only option (to be uploaded shortly).

Known limitations from my test cases so far:

On Wed, Feb 17, 2016 at 9:51 AM, alexperrone notifications@github.com wrote:

The option 1) remove NaNs/Infs was posted on the toolbox page by Eelke Spaak, this didn't work?

To fix this, I added the following around line 313, right before the actual calls to line() and patch(): % remove nans for k = 1:numel(xp) naninds = isnan(xp{k}) | isnan(yp{k}); xp{k} = xp{k}(~naninds); yp{k} = yp{k}(~naninds); end

Since it connects the points which were NaN, it basically linearly interpolates.

— Reply to this email directly or view it on GitHub https://github.com/kakearney/boundedline-pkg/issues/1#issuecomment-185323675 .