Filling the area in a plot without overlapping
12 views (last 30 days)
Show older comments
Lukas Schreiber
on 20 Apr 2023
Edited: chicken vector
on 20 Apr 2023
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 Comments
Accepted Answer
chicken vector
on 20 Apr 2023
Edited: chicken vector
on 20 Apr 2023
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 Comments
chicken vector
on 20 Apr 2023
Edited: chicken vector
on 20 Apr 2023
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
More Answers (0)
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!