Filling the area in a plot without overlapping
조회 수: 12 (최근 30일)
이전 댓글 표시
I want to fill the space between lines in a plot and the y=0 line with colour. The code creates three figures, with 3 lines in each figure. The difficulty is, that the lines in each figure are created elsewhere and can be above or below the y=0 line. Additionally, the data is connected, so that the fields belonging to the first line need to have the same colour in all 3 figures. So if y1(1,:) creates a red field in Figure 1, y2(1,:) needs to create a red field in Figure 2 as well. However, it is different data, so in the first figure, the line could be above y=0 and needs to be filled downwards and in the second it could be below and needs to be filled upwards. I tried it like this:
%example vectors (data coming from elsewhere)
c = rand(9,1);
y1 = (-10 + 20 * c(1:3)) .* (0:10).^2;
y2 = (-10 + 20 * c(4:6)) .* (0:10).^2;
y3 = (-10 + 20 * c(7:9)) .* (0:10).^2;
%plot drawing
for k = 1:3
x = 0:10;
figure
hold on
plot(x, y1(k,:), 'r')
plot(x, y2(k,:), 'b')
plot(x, y3(k,:), 'g')
x_fill = [x, fliplr(x)];
y1_fill = [y1(k,:), zeros(1, numel(x)),];
fill(x_fill, y1_fill, 'r', 'FaceAlpha', 0.1, 'EdgeColor', 'none');
y2_fill = [y2(k,:), zeros(1, numel(x))];
fill(x_fill, y2_fill, 'b', 'FaceAlpha', 0.1, 'EdgeColor', 'none');
y3_fill = [y3(k,:), zeros(1, numel(x))];
fill(x_fill, y3_fill, 'g', 'FaceAlpha', 0.1, 'EdgeColor', 'none');
end
It almost works, but the colour fields overlap, if there is a line in the middle between another line and the y=0 line. I don't want the colour fields to overlap other fields, but instead stop before the next field starts. Is there a way to do this?
댓글 수: 0
채택된 답변
chicken vector
2023년 4월 20일
편집: chicken vector
2023년 4월 20일
You can select the number of plots and curves you want using nPlots and nCurves, respectively.
You can also add more colors using, for example:
colors = {'r','g','b','c','m','y'};
Here's the code:
% Parameters:
nPlots = 3;
nCurves = 3;
colors = {'r','g','b'};
% X Axis data:
x = 0 : 10;
xFill = [x, fliplr(x)];
for j = 1 : nPlots
% Randomise curves:
c = sort(rand(nCurves,1),'descend');
y = (-10 + 20 * c) .* (0:10).^2;
% Create Y coordinates for fill:
yFillPos = y(c > .5,:);
yFillNeg = y(c <= .5,:);
yFill = [y, fliplr([yFillPos(2:end,:); zeros(~isempty(yFillNeg) + ~isempty(yFillPos),length(x)); yFillNeg(1:end-1,:)])];
% Initialise figure:
figure;
hold on;
% Loop over number of curves:
for k = 1 : nCurves
plot(x, y(k,:), colors{rem(k-1,length(colors))+1})
% Fill between curves:
fill(xFill, yFill(k,:), colors{rem(k-1,length(colors))+1});
end
end
Result with 50 curves:
Also, a small remark: you can make the code more robust by changing the following lines:
c = sort(rand(nCurves,1),'descend');
...
for k = 1 : nCurves
Into:
c = unique(sort(rand(nCurves,1),'descend'));
...
for k = 1 : length(c)
댓글 수: 2
chicken vector
2023년 4월 20일
편집: chicken vector
2023년 4월 20일
A re-adaption of the previous code to your needs.
Now using colors{idx(k)} makes sure that same y share same colors across plots.
% Parameters:
nPlots = 3;
nCurves = 3;
colors = {'r','g','b'};
% X Axis data:
x = 0 : 10;
xFill = [x, fliplr(x)];
% Randomise curves:
c = rand(nCurves,1,nPlots);
Y = (-10 + 20 * c) .* (0:10).^2;
for j = 1 : nPlots
% Use property of previous code on each figure:
[csort,idx] = sort(c(:,j),'descend');
y = Y(idx,:,j);
% Create Y coordinates for fill:
yFillPos = y(csort > .5,:);
yFillNeg = y(csort <= .5,:);
yFill = [y, fliplr([yFillPos(2:end,:); zeros(~isempty(yFillNeg) + ~isempty(yFillPos),length(x)); yFillNeg(1:end-1,:)])];
% Initialise figure:
figure;
hold on;
% Loop over number of curves:
for k = 1 : nCurves
plot(x, y(k,:), colors{idx(k)})
% Fill between curves:
fill(xFill, yFill(k,:), colors{idx(k)}, 'FaceAlpha', 0.1, 'EdgeColor', 'none');
end
end
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!