Search code examples
matlabplotfigure

Data evaluation


I have some data in MATLAB, and want to distinguish the start and stop point when these data cross specified threshold (for example -50), and save them and then calculate the approximate area of that section under -50 and if it was below some defined value neglect those points and check for the next two points. See the following image:

Figure

The two points on the left side of the figure are marked with x in red and the required area is shown in green. I want to do this for the whole figure.

Any idea? Thanks.


Solution

  • Regarding the plotting, there were possible ways mentioned in the comments, whereas I commonly would use patch to plot filled polygonal regions. For the area approximation, you can use the trapz function for a trapezoidal numerical integration.

    That'd be my solution, including detection of the intervals, and also neglecting intervals with insufficient area (it's a bit lengthy, and full of loops for plotting all the intervals; can be certainly optimized):

    % Set up function, and parameter(s)
    x = linspace(-0.125*pi, 4.125*pi, 10001);
    y = linspace(60, 100, 10001) .* sin(x);
    thr = -50;
    thr_area = 30;
    
    % Find y values lower than threshold
    y_idx = find(y <= thr);
    
    % Get start and end of intervals
    idx_int = find(diff(y_idx) > 1);
    n_int = numel(idx_int)+1;
    s = zeros(n_int, 1);
    e = zeros(n_int, 1);
    s(1) = y_idx(1);
    e(end) = y_idx(end);
    for k = 1:n_int-1
      e(k) = y_idx(idx_int(k));
      s(k+1) = y_idx(idx_int(k)+1);
    end
    
    % Calculate areas
    Q = zeros(n_int, 1);
    for k = 1:n_int
      Q(k) = abs(trapz(x(s(k):e(k)), y(s(k):e(k))-thr));
    end
    
    % Visualization
    figure(1);
    hold on;
    plot(x, y);
    xlim([x(1), x(end)]);
    ylim([min(y)-10, max(y)+10]);
    plot([x(1), x(end)], [thr thr], 'k');
    for k = 1:n_int
      patch(x(s(k):e(k)), y(s(k):e(k)), 'k');
      plot([x(s(k)), x(e(k))], [y(s(k)), y(e(k))], 'r.', 'MarkerSize', 15);
      text(x(s(k)), thr+20, num2str(Q(k)));
      if (Q(k) < thr_area)
        text(x(s(k)), thr+10, 'Area too low');
      else
        text(x(s(k)), thr+10, 'Area OK');
      end
    end
    hold off;
    

    The result looks like this:

    Output

    You should have all information by now to do whatever further calculations, analyses, etc. you have in mind.

    Hope that helps!

    Disclaimer: I tested the code with Octave 5.1.0, but I'm quite sure, that it should be fully MATLAB-compatible. If not, please leave a comment, and I'll try to fix possible issues.