2

我正在实时生成一个情节。我每 30 秒将 x 轴移动 30 秒。这一切都很好,但是我的 y 轴会自动调整大小,使其比以前更小。看看下面:

在 30 秒阈值之前绘制 - Y 限制为 [-1 1]

这是在我们达到 30 秒并重新绘制 x 轴标签之前的数据。我现在只是在绘图±cos(t),所以我的 Y 限制是 [-1 1]。

30 秒阈值后 - Y 限制为 [-0.8 0.5]

30 秒后,我将坐标轴移过来,开始观察在时间间隔 [30 60] 上生成的图。请注意,我的 Y 限制已重新调整为 [-0.8 0.5]。随着时间的增加,限制会回到 [-1 1]。但是我希望在前一个 30 秒快照和当前快照之间及时保持连续性,即限制应该在达到 30 秒阈值后立即为 [-1 1]。

有没有办法保持以前的 Y 限制并仍然让它们正常增长(即,如果 Y 数据超出限制,它将自动适当地调整大小)?

4

3 回答 3

1

这可能不像你想的那样“自动”,但我会做这样的事情。

new_axes = function resize_axes(x_data, y_data, x_increment)

old_axes = axis();
new_axes = old_axes;
if max(x_data(:)) > old_axes(2)
    new_axes(2) = new_axes(2) + x_increment; # e.g., 30 seconds
    new_axes(1) = old_axes(2);  # if you want the new axes to start
                                #  where the old ones ended
end
if max(y_data(:)) > old_axes(4)
    new_axes(4) = max(y_data(:));
end
if min(y_data(:)) < old_axes(3)
    new_axes(3) = min(y_data(:));
end

axis(new_axes);

然后在绘制新数据时调用 resize_axes 。

于 2011-09-09T20:56:23.710 回答
1

YLimMode如果轴的 设置为,y 轴范围将自动重新缩放auto。设置它manual以防止这种情况:

>> set(gca, 'YLimMode', '手动');

为了在图上的数据更新时将限制自动更新为适当的值,您可以使用事件侦听器侦听对线的更新。这种方法要求您通过更新线的属性来更新绘制的XData线YData。创建线路和侦听器:

>> h = line('XData', [], 'YData', []);
>> addlistener(h, 'YData', 'PostSet', @(src, evnt) set(evnt.AffectedObject.Parent, 'YLim', [min(evnt.AffectedObject.YData) max(evnt.AffectedObject.YData)] ));

侦听器定义包括一个匿名函数,该函数使用事件属性访问线的父级(即轴)并将 y 轴限制设置为绘制的 y 值的最小值和最大值。此函数YData在绘制线的属性更新时执行。

要查看此操作,请尝试以下操作:

>> x = 1;
>> y = cos(x);
>> 对于 ii = 2:1000
x(结束+1) = ii;
y(end+1) = cosd(x(end));
设置(h,'XData',x,'YData',y);
暂停(0.01);
结尾
于 2011-09-09T21:04:16.477 回答
1

如果您仍然对该问题感兴趣,请考虑以下示例。

基本上我们维护一个值缓冲区,用于在每次迭代时设置行数据。我们关闭了自动轴限制,而是仅在必要时自行更新它们。

生成的动画快速且响应迅速(实际上我用一个小的 PAUSE 减慢了它的速度),特别是因为我们只维护线条的可见部分的值(我们只是丢弃/覆盖旧值)。

我正在使用两个一维随机游走信号而不是余弦函数。这些序列预计将在两个方向上保持增长,轴不断调整其限制。可以轻松更改代码以绘制两个以上的信号。

%# setup axis and lines
N = 60;             %# window size (60 sec)
XLIMS = [1 N];      %# starting axis limits
YLIMS = [-1 1];
hAx = axes('XLim',XLIMS, 'YLim',YLIMS, 'Box','on', ...
    'YLimMode','manual', 'XLimMode','manual');
hLine1 = line('XData',1:N, 'YData',nan, 'Color','b', ...
    'Parent',hAx, 'YLimInclude','off');
hLine2 = line('XData',1:N, 'YData',nan, 'Color','r', ...
    'Parent',hAx, 'YLimInclude','off');

%# initialize vectors
y1 = nan(N,1);
y2 = nan(N,1);
ind = 1;
val1 = 0; val2 = 0;

while true
    %# get new values, and insert them in vectors
    val1 = val1 + (rand-0.5);
    val2 = val2 + (rand-0.5);
    y1(ind) = val1;
    y2(ind) = val2;

    %# update lines data
    set(hLine1, 'YData',y1)
    set(hLine2, 'YData',y2)

    %# keep track of smallest/largest values seen
    mn = min(val1,val2); mx = max(val1,val2);
    if mn<YLIMS(1), YLIMS(1) = mn; flag = true; end
    if mx>YLIMS(2), YLIMS(2) = mx; flag = true; end

    %# update axis Y-limits if needed
    if flag
        set(hAx, 'YLim',YLIMS); flag = false;
    end

    %# refresh plot
    drawnow, pause(0.02)

    %# circularly increment counter
    ind = ind + 1;
    if ind>N
        %# perparing for next cycle
        ind = 1;
        y1(:) = nan; y2(:) = nan;

        %# update axis x-limits and slide line x-data
        set(hAx, 'XLim',get(hAx,'XLim')+N);
        set(hLine1, 'XData',get(hLine1,'XData')+N);
        set(hLine2, 'XData',get(hLine2,'XData')+N);
    end

    %# break in case you close the figure
    if ~ishandle(hAx), break, end
end

截屏

于 2011-10-23T08:52:33.027 回答