Fill area between two lines
118 views (last 30 days)
Show older comments
Hello all,
I am trying to fill the area between two lines in a 2d graph. As you can see from the result picture provided, the area BETWEEN the lines isn't filled, but the area but the area between X0 and Xend is filled. Here is my code, hoping one of you can help!
Thanks!
hold on
plot(xxO, envelopeminO, 'k--', 'LineWidth', 1, 'DisplayName', 'Envelope Min');
plot(xxO, envelopesupO, 'k--', 'LineWidth', 1, 'DisplayName', 'Envelope Max');
% Remove NaN values from envelopesupE and envelopeminE
envelopesupO = rmmissing(envelopesupO);
envelopeminO = rmmissing(envelopeminO);
% Remove corresponding values from xxE
xxO = xxO(~isnan(envelopesupO));
fill([xxO' fliplr(xxO')], [envelopeminO fliplr(envelopesupO)], 'r', 'EdgeColor', 'none')
hold off
1 Comment
Voss
on 4 Mar 2024
Not specific to the fill question, but this line
% Remove corresponding values from xxE
xxO = xxO(~isnan(envelopesupO));
doesn't remove any elements from xxO because envelopesupO has no NaNs at that point. Any NaNs in envelopesupO were just removed by rmmissing two lines before.
I think you actually want to remove elements of xxO where either envelopesupO or envelopeminO was NaN.
% Remove NaN values from envelopesupE and envelopeminE, as well as
% corresponding values from xxO:
idx = isnan(envelopesupO) | isnan(envelopeminO);
envelopesupO(idx) = [];
envelopeminO(idx) = [];
xxO(idx) = [];
Answers (3)
Voss
on 4 Mar 2024
It looks like xxO is a row vector and envelopeminO and envelopesupO are column vectors (any other combination would work properly or generate an error).
First, reproducing the problem:
xxO = 1:130;
envelopeminO = cosd(xxO.').*(1-xxO.'/130);
envelopesupO = cosd(xxO.').*(3-xxO.'/130);
figure
hold on
plot(xxO, envelopeminO, 'k--', 'LineWidth', 1, 'DisplayName', 'Envelope Min');
plot(xxO, envelopesupO, 'k--', 'LineWidth', 1, 'DisplayName', 'Envelope Max');
% Remove NaN values from envelopesupE and envelopeminE
envelopesupO = rmmissing(envelopesupO);
envelopeminO = rmmissing(envelopeminO);
% Remove corresponding values from xxE
xxO = xxO(~isnan(envelopesupO));
fill([xxO' fliplr(xxO')], [envelopeminO fliplr(envelopesupO)], 'r', 'EdgeColor', 'none')
hold off
Now, fixing the problem:
Change your fill code to:
fill([xxO fliplr(xxO)], [envelopeminO.' fliplr(envelopesupO.')], 'r', 'EdgeColor', 'none')
figure
hold on
plot(xxO, envelopeminO, 'k--', 'LineWidth', 1, 'DisplayName', 'Envelope Min');
plot(xxO, envelopesupO, 'k--', 'LineWidth', 1, 'DisplayName', 'Envelope Max');
% Remove NaN values from envelopesupE and envelopeminE
envelopesupO = rmmissing(envelopesupO);
envelopeminO = rmmissing(envelopeminO);
% Remove corresponding values from xxE
xxO = xxO(~isnan(envelopesupO));
fill([xxO fliplr(xxO)], [envelopeminO.' fliplr(envelopesupO.')], 'r', 'EdgeColor', 'none')
hold off
0 Comments
Daniel
on 4 Mar 2024
It's hard to say for sure without seeing the input data, but my guess would be that your xxO is a row vector and your envelopes are column vectors. When you transpose xxO, you're turning a row vector into a column vector, and the resultant concatenation of rows is forming a 2xN matrix rather than a row vector. If that's the case, you just need to ensure that the outputs of your concatenations are vectors.
E.g. (and this can only be a guess, since I don't have the source data set),
fill([xxO fliplr(xxO)], [envelopeminO' fliplr(envelopesupO')], 'r', 'EdgeColor', 'none')
Here's an example with a different data set:
rng('default')
x = 0:10; % Row vector
y1 = rand(11,1); % Column vector
y2 = rand(11,1) + 5; % Column vector
plot(x,y1,x,y2) % No issue with a mix of row vectors and column vectors
title('Boundary data')
figure
fill([x' flip(x')],[y1 flip(y2)],'r') % Mimicking your code
title('Filled in wrong')
size(x) % x is a row vector -- 1xN
size(x') % So x' is a column vector -- Nx1
size([x' flip(x')]) % If you concatenate two column vectors along the rows, you'll get an Nx2 matrix
figure
% If you flip the column vectors to become row vectors you can perform horizontal concatenation
fill([x flip(x)],[y1' flip(y2')],'r')
title('Filled in right')
% You could also do this a few other ways:
figure
fill([x';flip(x')],[y1;flip(y2)],'r')
figure
fill([x flip(x)],[y1;flip(y2)],'r')
0 Comments
William Rose
on 4 Mar 2024
Since we do not have your data (xxO, envelopeminO, envelopesupO), I have made up some values to use for the example below.
xxO=linspace(0,130,131);
envelopeminO=1-xxO/100-2*sin(2*pi*xxO/130)/4;
envelopesupO=2.7-xxO/200-sin(2*pi*xxO/260);
% Next: plot the filled are between curves
x=[xxO,fliplr(xxO)];
y=[envelopesupO,fliplr(envelopeminO)];
fill(x,y,'r')
0 Comments
See Also
Categories
Find more on 2-D and 3-D Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!