MATLAB, Filling in the area between two sets of data, lines in one figure

175,890

Solution 1

Building off of @gnovice's answer, you can actually create filled plots with shading only in the area between the two curves. Just use fill in conjunction with fliplr.

Example:

x=0:0.01:2*pi;                  %#initialize x array
y1=sin(x);                      %#create first curve
y2=sin(x)+.5;                   %#create second curve
X=[x,fliplr(x)];                %#create continuous x value array for plotting
Y=[y1,fliplr(y2)];              %#create y values for out and then back
fill(X,Y,'b');                  %#plot filled area

enter image description here

By flipping the x array and concatenating it with the original, you're going out, down, back, and then up to close both arrays in a complete, many-many-many-sided polygon.

Solution 2

Personally, I find it both elegant and convenient to wrap the fill function. To fill between two equally sized row vectors Y1 and Y2 that share the support X (and color C):

fill_between_lines = @(X,Y1,Y2,C) fill( [X fliplr(X)],  [Y1 fliplr(Y2)], C );

Solution 3

You can accomplish this using the function FILL to create filled polygons under the sections of your plots. You will want to plot the lines and polygons in the order you want them to be stacked on the screen, starting with the bottom-most one. Here's an example with some sample data:

x = 1:100;             %# X range
y1 = rand(1,100)+1.5;  %# One set of data ranging from 1.5 to 2.5
y2 = rand(1,100)+0.5;  %# Another set of data ranging from 0.5 to 1.5
baseLine = 0.2;        %# Baseline value for filling under the curves
index = 30:70;         %# Indices of points to fill under

plot(x,y1,'b');                              %# Plot the first line
hold on;                                     %# Add to the plot
h1 = fill(x(index([1 1:end end])),...        %# Plot the first filled polygon
          [baseLine y1(index) baseLine],...
          'b','EdgeColor','none');
plot(x,y2,'g');                              %# Plot the second line
h2 = fill(x(index([1 1:end end])),...        %# Plot the second filled polygon
          [baseLine y2(index) baseLine],...
          'g','EdgeColor','none');
plot(x(index),baseLine.*ones(size(index)),'r');  %# Plot the red line

And here's the resulting figure:

enter image description here

You can also change the stacking order of the objects in the figure after you've plotted them by modifying the order of handles in the 'Children' property of the axes object. For example, this code reverses the stacking order, hiding the green polygon behind the blue polygon:

kids = get(gca,'Children');        %# Get the child object handles
set(gca,'Children',flipud(kids));  %# Set them to the reverse order

Finally, if you don't know exactly what order you want to stack your polygons ahead of time (i.e. either one could be the smaller polygon, which you probably want on top), then you could adjust the 'FaceAlpha' property so that one or both polygons will appear partially transparent and show the other beneath it. For example, the following will make the green polygon partially transparent:

set(h2,'FaceAlpha',0.5);

Solution 4

You want to look at the patch() function, and sneak in points for the start and end of the horizontal line:

x = 0:.1:2*pi;
y = sin(x)+rand(size(x))/2;

x2 = [0 x 2*pi];
y2 = [.1 y .1];
patch(x2, y2, [.8 .8 .1]);

If you only want the filled in area for a part of the data, you'll need to truncate the x and y vectors to only include the points you need.

Share:
175,890
Josh
Author by

Josh

Updated on July 09, 2022

Comments

  • Josh
    Josh almost 2 years

    I have a question about using the area function; or perhaps another function is in order... I created this plot from a large text file:

    http://img818.imageshack.us/img818/9519/iwantthisareafilledin.jpg

    The green and the blue represent two different files. What I want to do is fill in the area between the red line and each run, respectively. I can create an area plot with a similar idea, but when I plot them on the same figure, they do not overlap correctly. Essentially, 4 plots would be on one figure.

    I hope this makes sense.

  • Josh
    Josh almost 13 years
    Thank you, I will look into this patch function today!
  • Josh
    Josh almost 13 years
    This also looks very promising. I didn't think attempt a method such as this. I will update you when I have my attempt.
  • Alex
    Alex almost 13 years
    patch() is the lower-level version of fill() so either this or gnovice's answer should do what you want.
  • webelo
    webelo over 8 years
    One more tip concerning fliplr: If your vectors are nx1 but you need to plot them as an 1xn (for whatever reason), take the prime inside. i.e. yb = [y1',fliplr(y2')]. Not yb = [y1',fliplr(y2)'].
  • ftxx
    ftxx about 7 years
    Can we make the shade region filled with "+" or other different Marker?
  • Doresoom
    Doresoom about 7 years
    @ftxx Sure, if you want to populate the area between the two curves with a matrix, and then plot it with a "+" for a point marker.
  • Windy Day
    Windy Day almost 6 years
    did nothing for lines
  • MrIO
    MrIO almost 6 years
    @MelB, can you be more explicit?
  • Doresoom
    Doresoom almost 6 years
    @MelB Got the code that didn't work? It should work for any set of points that's properly constructed.