我正在实时制作情节。我每隔30秒将x轴移动30秒。这一切都很好,但我的y轴自动调整大小比以前小。看看下面:
在我们达到30秒并重新绘制x轴标签之前,这是我的数据。我现在正在密谋±cos(t)
,所以我的Y限制是[-1 1]。
在30秒之后,我将轴移开以开始观察在时间间隔[30 60]上生成的图。请注意,我的Y限制已重新调整为[-0.8 0.5]。随着时间的推移,限制可以追溯到[-1 1]。但我希望在之前的30秒快照与当前快照之间保持连续性,即在达到30秒阈值后,限制应立即为[-1 1]。
有没有办法保持之前的Y限制并仍让它们正常生长(即,如果Y数据超出限制,它会自动调整大小,自动调整)?
答案 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监听行的更新。此方法要求您通过更新行的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)]));
侦听器定义包括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