我面前没有 MATLAB,也没有你的数据来测试这个,所以这是一个大概的答案,但正如 @natan 在上面的 cmets 中提到的那样,你可以从该图形存储在“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 全部为假,就会出现这种情况。在这种情况下,您需要左轴外的最大点和右轴外的最小点。如果这些搜索中的任何一个为空,则该行不会通过窗口并且可以被丢弃。
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