Fill area between different curves

I cannot find a command to fill the area between the maximum and minimum values of these curves:
x1 = [0 1 2.2 4];
y1 = [0.5 2 1.8 1];
x2 = [0 1.2 2 4];
y2 = [0 1 2 1.5];
x3 = [0 1 3 3.5];
y3 = [0 1 2 1.5];
figure
plot(x1,y1);
hold on
plot(x2,y2);
hold on
plot(x3,y3);
I attached an image for better understand my request. Unfortunately, I found a solution just if Y is depending of X (e.g. : https://www.mathworks.com/matlabcentral/answers/180829-shade-area-between-graphs)

2 Comments

So your problem is now solved?
no. My case is different from the e.g. found. I have "y" not depending of "x"

Sign in to comment.

 Accepted Answer

It’s necessary to create common (x,y) values for all the curves with interpolation. Then the solution is straightforward.
If I understand correctly what you want, this works:
x1 = [0 1 2.2 4];
y1 = [0.5 2 1.8 1];
x2 = [0 1.2 2 4];
y2 = [0 1 2 1.5];
x3 = [0 1 3 3.5];
y3 = [0 1 2 1.5];
xm = [x1; x2; x3]; % Create ‘X’ Matrix
xl = [min(xm(:)) max(xm(:))];
xu = linspace(xl(1), xl(2), 1000); % Create Sorted Interpolation Vector
ym = [y1; y2; y3]; % Create ‘Y’ Matrix
for k1 = 1:size(xm,1)
yi(k1,:) = interp1(xm(k1,:), ym(k1,:), xu, 'linear','extrap'); % Interpolate To Provide Common (x,y) Values
end
ymin = min(yi);
ymax = max(yi);
figure
patch([xu(:)' fliplr(xu(:)')], [ymin fliplr(ymax)], [0.1 0.9 0.1], 'FaceAlpha',0.3) % Plot Filled Background
hold on
plot(x1,y1)
plot(x2,y2)
plot(x3,y3)

10 Comments

if I use my experimental data (not the simple data posted above) i receive this error code:
Error using griddedInterpolant
Interpolation requires at least two sample points in each dimension.
Error in interp1 (line 149)
F = griddedInterpolant(X,V,method);
Error in DiagonalTest_sizeParticlesEffect (line 112)
yi(k1,:) = interp1(xm(k1,:), ym(k1,:), xu, 'linear','extrap'); %
Interpolate To Provide Common (x,y) Values
I would have to know more about your data to determine how to solve your problem.
If your data are in cell arrays, use the cell2mat function first. (Cell arrays would probably throw a different error, although this may be version-dependent.)
I'm attaching the code and the file "HIST.txt":
clear all
load HIST.txt;
x1=HIST(:,1);
y1=HIST(:,2);
x2=HIST(:,3);
y2=HIST(:,4);
x3=HIST(:,5);
y3=HIST(:,6);
xm = [x1; x2; x3]; % Create ‘X’ Matrix
xl = [min(xm(:)) max(xm(:))];
xu = linspace(xl(1), xl(2), 1000); % Create Sorted Interpolation Vector
ym = [y1; y2; y3]; % Create ‘Y’ Matrix
for k1 = 1:size(xm,1)
yi(k1,:) = interp1(xm(k1,:), ym(k1,:), xu, 'linear','extrap'); % Interpolate To Provide Common (x,y) Values
end
ymin = min(yi);
ymax = max(yi);
figure
patch([xu(:)' fliplr(xu(:)')], [ymin fliplr(ymax)], [0.1 0.9 0.1], 'FaceAlpha',0.3) % Plot Filled Background
hold on
plot(x1,y1)
plot(x2,y2)
plot(x3,y3)
Your actual data are column vector, not row vectors. (They are row vectors in your original post.) That required some changes in your code, and since in the interpolation, the independent ‘x’ variables must contain no duplicate values, required a call to the unique function to create them as such. Also, the third group is 1 element longer than the others, so I eliminated the values at x3(1), since that is 0 and none of the other ‘x’ vectors begins at 0.
With those changes, this works:
x1=HIST(:,1)';
y1=HIST(:,2)';
x2=HIST(:,3)';
y2=HIST(:,4)';
x3=HIST(:,5)';
y3=HIST(:,6)';
[x1u,ia1] = unique(x1); % Eliminate Duplicates, Return Unique Values & Indices
[x2u,ia2] = unique(x2);
[x3u,ia3] = unique(x3);
xm = [x1u; x2u; x3u(2:end)]; % Create ‘X’ Matrix
xl = [min(xm(:)) max(xm(:))];
xu = linspace(xl(1), xl(2), 1000); % Create Sorted Interpolation Vector
ym = [y1(ia1); y2(ia2); y3(ia3(2:end))]; % Create ‘Y’ Matrix
for k1 = 1:size(xm,1)
yi(k1,:) = interp1(xm(k1,:), ym(k1,:), xu, 'linear','extrap'); % Interpolate To Provide Common (x,y) Values
end
ymin = min(yi);
ymax = max(yi);
figure
patch([xu(:)' fliplr(xu(:)')], [ymin fliplr(ymax)], [0.1 0.9 0.1], 'FaceAlpha',0.3) % Plot Filled Background
hold on
plot(x1,y1)
plot(x2,y2)
producing:
the code is ok for that case, but if I try to use it for other cases I have the same problem described above. I have already checked your suggestion but doesn't work. Maiby is a silliness to change but I cannot solve myself
My code works. I had to adjust the vector lengths of your previous data to make them equal. Your current data don’t have that problem.
Try this:
[x1u,ia1] = unique(x1); % Eliminate Duplicates, Return Unique Values & Indices
[x2u,ia2] = unique(x2);
[x3u,ia3] = unique(x3);
xm = [x1u; x2u; x3u]; % Create ‘X’ Matrix
xl = [min(xm(:)) max(xm(:))];
xu = linspace(xl(1), xl(2), 1000); % Create Sorted Interpolation Vector
ym = [y1(ia1); y2(ia2); y3(ia3)]; % Create ‘Y’ Matrix
for k1 = 1:size(xm,1)
yi(k1,:) = interp1(xm(k1,:), ym(k1,:), xu, 'linear','extrap'); % Interpolate To Provide Common (x,y) Values
end
ymin = min(yi);
ymax = max(yi);
figure
patch([xu(:)' fliplr(xu(:)')], [ymin fliplr(ymax)], [0.1 0.9 0.1], 'FaceAlpha',0.3) % Plot Filled Background
hold on
plot(x1,y1)
Thank you so much. The last question. Do you know the command to read the first "n" line (e.g. n=5000) from the external file to avoid the problem of the vector lengths?
As always, my pleasure.
I would read all the data in, then trim them to the length of the shortest of the data vectors. However, you need to look at them first, if all the lengths are not the same.
First, be certain that the initial values are all about the same. In your previous set, one vector (that was one element longer than the others) began with 0 while the others began far above 0. That was the reason I omitted the first element of the vector that was one element longer than the others.
If they pass that test, then just find the row size of the shortest vector and trim the others to be the same lengths. (In your latest set, they were all the same lengths, so that problem didn’t exist.)
So be sure that the initial element of each vector is the same magnitude as the others, then if necessary, trim the others to the length of the shortest vector.
So, isn't there a specific command to trim data on a certain line (for which I am sure that all data has the same length)? This is because I've more than thousands of data and I would like to avoid checking them manually. Moreover, I'm asking you this because I don't need all the data and I could use less; if there is a difference of vector length is maximum of ten line.
There’s no one specific command. You would first need to use the size function to determine the vector sizes. Then compare the row size (dimension 1, so size(data,1) if ‘data’ is your array name), then compare them.
One way to do the initial check is:
sz1 = 200; % Row Size Of First Data Set
sz2 = 201; % Row Size Of Second Data Set
sz3 = 211; % Row Size Of Third Data Set
sz_eq = isequal(sz1, sz2, sz3); % If All Are Equal=1, Not Equal = 0
min_rows = min([sz1 sz2 sz3]); % Minimum Row Size
max_rows = max([sz1 sz2 sz3]); % Maximum Row Size
You can of course define other criteria. Then trim your data matrices as you wish, the only constraint being that the ‘trimmed’ row size is less than ‘min_rows’.

Sign in to comment.

More Answers (0)

Categories

Tags

Community Treasure Hunt

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

Start Hunting!