【问题标题】:How to cut part of the data out of a plot in Matlab如何从 Matlab 中的绘图中截取部分数据
【发布时间】:2021-02-15 04:18:05
【问题描述】:

我只是想在 MATLAB 中截取部分数据,例如: 如果我点击轴上的两个点,它会在我点击后相对于 x 轴切割元素。我将发布我的代码和图片以获取更多详细信息 提前谢谢你

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

【问题讨论】:

    标签: matlab matlab-figure data-processing


    【解决方案1】:

    *将此作为格式代码的答案发布。

    如果它只有一个图形,您只需选择要删除的点,使用“画笔/选择数据”(图菜单栏上带有红色方块的画笔图标)选择您想要删除的数据消失,然后按删除键。

    如果您想使用代码来执行此操作,您可以尝试使用以下方法找到信号开始在 X 上减少的点的索引:

    % 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);
    

    如果要使用用户的点击位置,可以使用 find 定位点击后第一个元素的索引:

    % 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);
    

    然后只需绘制 saveData。


    编辑

    我之前的代码有错别字,这里有一个功能齐全的示例,您只需单击要裁剪的两个点即可。

    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
    

    【讨论】:

    • 您好,如果我希望第一次点击大于 1,最终点击小于 100。我应该分配 firstXIndex > 1 并且下一行是 firstXIndex = find(data.x >= xCoordInit);对于最终点击,我应该做 finalXIndex xCoordFinal); ?谢谢
    • 您想将其设置为硬编码限制还是仅提供示例值?
    • 无论如何,如果要确保第一个索引大于 1 是的。代码应如下所示: xCoordInit = 1; firstXIndex = find(data.x > xCoordInit);关于 finalIndex,如果你使用 'finalXIndex = find(data.x
    • 这就是为什么我建议使用 'finalXIndex = find(data.x > xCoordFinal); finalXIndex = finalXIndex(1)-1;',如您所知,'finalXIndex(1)-1' 将对应于开始循环之前的第一个索引。 (假设符合图下部的点位于data.x和data.y的最前面)。
    • 当我尝试使用您提供的第二段代码时,系统无法识别 'firstXIndex = find(data.x >= xCoordInit); '。只是想问我应该在它之前初始化一些东西吗?
    猜你喜欢
    • 2015-02-06
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 2013-02-07
    相关资源
    最近更新 更多