Filling the area in a plot without overlapping

10 visualizaciones (últimos 30 días)
Lukas Schreiber
Lukas Schreiber el 20 de Abr. de 2023
Editada: chicken vector el 20 de Abr. de 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?

Respuesta aceptada

chicken vector
chicken vector el 20 de Abr. de 2023
Editada: chicken vector el 20 de Abr. de 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 comentarios
Lukas Schreiber
Lukas Schreiber el 20 de Abr. de 2023
Thank you. This is a really good answer, but I explained my question poorly. I updated the question and the code a little bit to make it more clear what I mean.
chicken vector
chicken vector el 20 de Abr. de 2023
Editada: chicken vector el 20 de Abr. de 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

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre 2-D and 3-D Plots en Help Center y File Exchange.

Productos


Versión

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by