
Filling the area in a plot without overlapping
10 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Lukas Schreiber
il 20 Apr 2023
Modificato: chicken vector
il 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 Commenti
Risposta accettata
chicken vector
il 20 Apr 2023
Modificato: chicken vector
il 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 Commenti
chicken vector
il 20 Apr 2023
Modificato: chicken vector
il 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
Più risposte (0)
Vedere anche
Categorie
Scopri di più su 2-D and 3-D Plots in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!