MATLAB - 在图中动态调整x轴但不调整y轴吗?

时间:2011-09-09 20:27:50

标签: matlab plot dynamic-data figures real-time-data

我正在实时制作情节。我每隔30秒将x轴移动30秒。这一切都很好,但我的y轴自动调整大小比以前小。看看下面:

Plot before 30 second threshold - Y limits are [-1 1]

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

After 30 second threshold -  Y limits are [-0.8 0.5]

在30秒之后,我将轴移开以开始观察在时间间隔[30 60]上生成的图。请注意,我的Y限制已重新调整为[-0.8 0.5]。随着时间的推移,限制可以追溯到[-1 1]。但我希望在之前的30秒快照与当前快照之间保持连续性,即在达到30秒阈值后,限制应立即为[-1 1]。

有没有办法保持之前的Y限制并仍让它们正常生长(即,如果Y数据超出限制,它会自动调整大小,自动调整)?

3 个答案:

答案 0 :(得分: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。

答案 1 :(得分:1)

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

>> set(gca, 'YLimMode', 'manual');

为了在更新绘图上的数据时让限制自动更新为适当的值,您可以使用event listener监听行的更新。此方法要求您通过更新行的XDataYData属性来更新绘制的行。创建行和监听器:

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

侦听器定义包括anonymous function,它使用事件属性访问线的父级(即轴),并将y轴限制设置为绘制的y值的最小值和最大值。当绘制线的YData属性更新时,将执行此功能。

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

>> x = 1;
>> y = cos(x);
>> for ii = 2:1000
x(end+1) = ii;
y(end+1) = cosd(x(end));
set(h, 'XData', x, 'YData', y);
pause(0.01);
end

答案 2 :(得分:1)

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

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

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

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

%# 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

screenshot