在Matlab中保存裁剪的数字

我用matlab和openfig从文件中打开了一个高度复杂的.fig图.

在此之后我用这个数字裁剪了

轴([X1,X2,Y1,Y2])

我现在想要保存裁剪的数字,以便在保存时缩小尺寸.问题是savefig会将缩放的完整图像保存到指定的轴.如何保存图形,永久裁剪到我指定的轴上?例如打开新图像时无法缩小.

最佳答案 我没有MATLAB在我面前,我没有你的数据来测试这个,所以这是一个近似的答案,但正如@natan在上面的评论中提到的,你可以从图中收集数据,它存储在’XData’和’YData’中.然后,您可以将数据裁剪为所需的部件,然后使用裁剪的数据替换现有数据.它最终会看起来像这样:

kids = findobj(gca,'Type','line');
K = length(kids);

Xrange = get(gca,'XLim');
Yrange = get(gca,'YLim');

for k = 1:K
    X = get(kids(k),'XData');
    Y = get(kids(k),'YData');

    idx = X >= min(Xrange) & X <= max(Xrange) & Y >= min(Yrange) & Y <= max(Yrange);

    set(kids(k),'XDATA',X(idx),'YDATA',Y(idx));
end

如果你的图有补丁对象,条形对象等,你必须修改它,但想法就在那里.

边缘情况:

正如@Jan正确指出的那样,有一些边缘情况需要考虑.首先,即使在扩展的尺度上,上述方法也假定点的密度相当高,并且在线的末端和轴之间留下小的间隙.对于低点密度线,您需要扩展idx变量以捕获轴外的下一个点:

idx_center = X >= min(Xrange) & X <= max(Xrange) & Y >= min(Yrange) & Y <= max(Yrange);
idx_plus = [false idx(1:end-1)];
idx_minus = [idx(2:end) false];

idx = idx_center | idx_plus | idx_minus;

如果窗口内至少有一个点,那只会扩大点数.另一个边缘情况是线穿过窗口但不包含窗口内的任何点,如果idx全为false则会出现这种情况.在这种情况下,您需要左轴外的最大点和右轴外的最小点.如果这些搜索中的任何一个变为空,则该行不会通过该窗口并且可以被丢弃.

if ~any(idx)
   idx_low = find(X < min(Xrange),1,'last');
   idx_high = find(X > max(Xrange),1,'first');

   if isempty(idx_low) | isempty(idx_high)
       % if there aren't points outside either side of the axes then the line doesn't pass through
       idx = false(size(X));
   else
       idx = idx_low:idx_high;
   end
end

这不会测试线是否在y边界内,因此线可能会在窗口的上方或下方通过而不会相交.如果这很重要,您将需要测试连接找到的点的线.内存中额外的2分应该不是什么大问题.如果这是一个问题,那么我将它作为练习留给学生来测试线是否通过轴.

把它们放在一起:

kids = findobj(gca,'Type','line'); % find children of the axes that are lines
K = length(kids); % count them

Xrange = get(gca,'XLim'); % get the axis limits
Yrange = get(gca,'YLim');

for k = 1:K
    X = get(kids(k),'XData'); % pull the x-y data for the line
    Y = get(kids(k),'YData');

    % find the points inside the window and then dilate the window by one in
    % each direction
    idx_center = X >= min(Xrange) & X <= max(Xrange) & Y >= min(Yrange) & Y <= max(Yrange);
    idx_plus = [false idx(1:end-1)];
    idx_minus = [idx(2:end) false];

    idx = idx_center | idx_plus | idx_minus;

    % handle the edge case where there are no points in the window but the line still passes through
    if ~any(idx)
       idx_low = find(X < min(Xrange),1,'last');
       idx_high = find(X > max(Xrange),1,'first');

       if isempty(idx_low) | isempty(idx_high)
           % if there aren't points outside either side of the axes then the line doesn't pass     
           % through
           idx = false(size(X));
       else
           % numerical indexing instead of logical, but it all works the same
           idx = idx_low:idx_high;
       end
    end

    if any(idx)
        % reset the line with just the desired data
        set(kids(k),'XDATA',X(idx),'YDATA',Y(idx));
    else
        % if there still aren't points in the window, remove the object from the figure
        delete(kids(k));
    end
end
点赞