Search code examples
matlabplotmatlab-figure

How can I highlight the overlapping area in a stairstep graph?


I'm trying to highlight the intersecting area of two stairstep graphs. I was able to select the points inside the intersecting area and wanted to create the filled shape with the patch command, which did not work out. However, some points still have to be excluded and the point of intersection has to be added.

Another idea was to create two area graphs, which look like staircase graphs with:

x = pc_bh(1, :);
y = pc_bh(2, :);
x = [x; x];
y = [y; y];
area(x([2:end end]),y(1:end))
hold on;
x = pc_bh(3, :);
y = pc_bh(4, :);
x = [x; x];
y = [y; y];
area(x([2:end end]),y(1:end))

and intersect them, which did not work either.

Here's the desired result:

enter image description here

Here's a plot with markers on the points inside the intersecting area:

enter image description here

The code for the markers is quite simple:

pointsA = [];
pointsB = [];
lowerLimit = pc_bh(3, 1);
upperLimit = pc_bh(1, 11);

for entry=2:11
   if pc_bh(1, entry) >= lowerLimit && pc_bh(1, entry) <= upperLimit
       pointsA = vertcat(pointsA, [pc_bh(1, entry), pc_bh(2, entry)]);
       pointsA = vertcat(pointsA, [pc_bh(1, entry), pc_bh(2, entry) + 1/10]);
   end
   if pc_bh(3, entry) >= lowerLimit && pc_bh(3, entry) <= upperLimit
       pointsB = vertcat(pointsB, [pc_bh(3, entry), pc_bh(4, entry)]);
           pointsB = vertcat(pointsB, [pc_bh(3, entry), pc_bh(4, entry) - 1/9]);
   end
end
plot(pointsA(:, 1), pointsA(:, 2), 'xr');
plot(pointsB(:, 1), pointsB(:, 2), 'xb');

The data set is a 4 x 11 matrix where the 1st/2nd row contain the x/y values for the first graph and the 3rd/4th row the x/y values for the second graph.

This is the data set used:

0.99754 0.99754 0.99772 0.99790 0.99808 0.99821 0.99842 0.99870 0.99886 0.99900 0.99918
1       0.9     0.8     0.7     0.6     0.5     0.4     0.3     0.2     0.1     0
0.99873 0.99873 0.99899 0.99918 0.99928 0.99945 0.99969 0.99973 0.99987 0.99993 0.99993
0       0.11111 0.22222 0.33333 0.44444 0.55555 0.66666 0.77777 0.88888 1       1

Solution

  • The difficulty arises from the fact that each stairstep plot is evaluated at a different set of x values. Essentially, you need to interpolate the value of each stairstep plot at the corresponding x values of the other so you can compare the y values at the same points to see which one is the minimum. Normal interpolation runs into problems because you have to have repeat x values in a stairstep plot. An alternative is to use the histcounts function to find for each plot which steps their points fall on for the other plot. Here's a function stairarea that illustrates this, taking two sets of x and y data as input and creating a plot using stairs and area:

    function stairarea(x1, y1, x2, y2)
    
      % Find overlap of curve 1 on curve 2:
      [~, ~, index] = histcounts(x1, x2);
      xi = x1(index > 0);
      yi = min(y1(index > 0), y2(index(index > 0)));
    
      % Find overlap of curve 2 on curve 1:
      [~, ~, index] = histcounts(x2, x1);
      xi = [xi x2(index > 0)];
      yi = [yi min(y2(index > 0), y1(index(index > 0)))];
    
      % Sort and create stairstep data for overlapping points:
      [xi, index] = sort(xi);
      yi = yi(index);
      [xi, yi] = stairs(xi, yi);
    
      % Create plot:
      area(xi, yi, 'FaceColor', 'y', 'EdgeColor', 'none');
      hold on;
      stairs(x1, y1, 'b');
      stairs(x2, y2, 'r');
    
    end
    

    And you can use this with your sample data like so:

    pc_bh = [0.99754 0.99754 0.99772 0.99790 0.99808 0.99821 0.99842 0.99870 0.99886 0.99900 0.99918; ...
             1       0.9     0.8     0.7     0.6     0.5     0.4     0.3     0.2     0.1     0; ...
             0.99873 0.99873 0.99899 0.99918 0.99928 0.99945 0.99969 0.99973 0.99987 0.99993 0.99993; ...
             0       0.11111 0.22222 0.33333 0.44444 0.55555 0.66666 0.77777 0.88888 1       1];
    stairarea(pc_bh(1, :), pc_bh(2, :), pc_bh(3, :), pc_bh(4, :));
    

    And you will get this plot:

    enter image description here