Fill area between two lines

조회 수: 117 (최근 30일)
Amélia
Amélia 2024년 3월 4일
답변: Daniel 2024년 3월 4일
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
Voss
Voss 2024년 3월 4일
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) = [];

댓글을 달려면 로그인하십시오.

답변 (3개)

Voss
Voss 2024년 3월 4일
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

Daniel
Daniel 2024년 3월 4일
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
ans = 1×2
1 11
size(x') % So x' is a column vector -- Nx1
ans = 1×2
11 1
size([x' flip(x')]) % If you concatenate two column vectors along the rows, you'll get an Nx2 matrix
ans = 1×2
11 2
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')

William Rose
William Rose 2024년 3월 4일
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')

카테고리

Help CenterFile Exchange에서 2-D and 3-D Plots에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by