简体   繁体   中英

How to cut part of the data out of a plot in Matlab

I just wanted to cut part of my data out in MATLAB, for example: If I click on two points on the axis, it will cut the elements after the I click on with respect to the x-axis. I will post my code and a pic for further details Thank you in advance

load sample.mat
X = sample.current;
X1 = sample.voltage;
Ts = 0.01;
  Fs = 1/Ts;
  Fm = Fs/2;
  Fc = 2;
  N =10;
  d = fdesign.lowpass('N,Fc',N,Fc,Fs);
  designmethods(d);
  Hd = design(d);
   %fvtool(Hd)
   %X is a variable form csv
   %X1 is a variable from csv
   output = filter(Hd,X);
   output1 = filter(Hd,X1);
   figure;
   plot(X,X1,'-g');
   hold on
   plot(output, output1,'r');
   hold off
   legend('raw signal','filtered signal')
   grid on
x = output, output1;
y = output1;
figure
subplot(2,1,1)
plot(x,y,'r');
title('Original plot');
uiwait(msgbox('Select an x-value from which to crop','modal'));
[x_user ~] = ginput(1); % Let the user select an x-value from which to crop.
x(x>x_user) = [];
subplot(2,1,2);
plot(x,y,'r');
title('New plot with cropped values');
xlim([min(x(:)) max(x(:))]);

enter image description here

*Posting this as an answer to format code.

If its only one graphic you can just select the points that you want to delete using the "Brush/Select Data" (icon of a brush with a red square located at the menubar of the figure) selecting the data you want to be gone and then pressing the delete key.

If you want to do it with code you can try to find the index of the point where the signal starts to decrease over the X using something like:

% Find the index where X starts to decrease
maxIndex = find(data.x == max(data.x));
% In case of multiple indexs, ensure we get the first one
maxIndex = maxIndex(1);

% Copy data to new vector 
saveData.x = data.x(1:maxIndex);
saveData.y = data.y(1:maxIndex);

If you want to use the users' click position you can use find to locate the index of the first element after the click:

% Get the coords of the first click
userFirstClick = ginput(1);
% Get the X component of the coords
xCoordInit = userFirstClick(1);
% Locate the index of the first element that is greater than 
% the xCoord
firstXIndex = find(data.x >= xCoordInit);
% In case of multiple indexs, ensure we get the first one
firstXIndex = firstXIndex(1);

% Do the same to get the final index
userSecondClick = ginput(1);
xCoordFinal = userSecondClick(1);
finalXIndex = find(data.x > xCoordFinal);
finalXIndex = finalXIndex(1)-1;
% -1 because data.x(finalXIndex) is already greater than xCoordFinal

% Copy data to the new vector
saveData.x = data.x(firstXIndex:finalXIndex);
saveData.y = data.y(firstXIndex:finalXIndex);

Then just plot saveData.


Edit

There was a typo on my previous code, here you have a fully functional example where you just need to click over the two points where you want to crop.

function cropSine()
    % create a period of a Sine to initialize our data
    data.x = -pi*3:0.01:pi*3;
    data.y = sin(data.x);

    % we make it loop back just as in your picture
    data.x = [data.x,data.x(end:-1:1)];
    data.y = [data.y, -data.y*0.5+5];

    % create a figure to show the signal we have just created
    figure
    % create the axes where the data will be displayed
    mainAx = axes();

    % Draw our fancy sine!
    plot(data.x, data.y, 'b-', 'Parent', mainAx);
    
    % Request the initial position to crop
    userFirstClick = ginput(1);
    % Get the index of the nearest point
    initIndex = getNearest(userFirstClick, data);
    
    % Do the same to get the final index
    userSecondClick = ginput(1);
    % Get the index of the nearest point
    finalIndex = getNearest(userSecondClick, data);
    
    
    % check if its a valid point
    if isempty(initIndex) || isempty(finalIndex)
        disp('No points in data vector!');
        return;
    end
    
    % Ensure that final index is greater than first index
    if initIndex > finalIndex
        tempVal = initIndex;
        initIndex = finalIndex;
        finalIndex = tempVal;
    end
        
    % Copy the data that we want to save into a new variable
    saveData.x = data.x(initIndex:finalIndex);
    saveData.y = data.y(initIndex:finalIndex);

    % Plot the cropped data in red!
    hold(mainAx, 'on');
    plot(saveData.x, saveData.y, 'r-', 'Parent', mainAx);
    hold(mainAx, 'off');
end

function nearestIndex = getNearest(clickPos, vector)
    nearestIndex = [];
    numPoints = length(vector.x);
    
    if numPoints == 0
        return;
    end
    
    nearestIndex = 1;
    
    minDist = calcDist(vector.x(1), vector.y(1), clickPos(1), clickPos(2));
    
    for pointID = 1:numPoints
        dist = calcDist(vector.x(pointID), vector.y(pointID), clickPos(1), clickPos(2));
        if dist < minDist
            nearestIndex = pointID;
            minDist = dist;
        end
    end
end

function dist = calcDist(p1x, p1y, p2x, p2y)
    dist = sqrt(power(p1x-p2x,2)+power(p1y-p2y,2));
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM