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

YLimMode軸の が に設定されている場合、y 軸の範囲は自動的に再スケーリングされautoます。manualこれを防ぐには、次のように設定します。

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

プロット上のデータが更新されたときに制限を適切な値に自動的に更新するには、イベント リスナーを使用して線の更新をリッスンできます。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(終了+1) = cosd(x(終了));
set(h, 'XData', x, 'YData', y);
一時停止(0.01);
終わり
于 2011-09-09T21:04:16.477 に答える
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

If you are still interested in the problem, then consider the following example.

Basically we maintain a buffer of values, used to set the lines data each iteration. We turn off automatic axis limits, and instead update them ourselves only when necessary.

The resulting animation is fast and responsive (I actually slowed it down with a small PAUSE), especially since we only maintain values for the visible portion of the lines (we simply discard/overwrite old values).

I am using two 1D random walk signals instead of cosine functions. These sequences are expected to keep growing in both directions, with the axis continuously adjusting its limits. The code can be easily changed to plot more than two signals.

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

于 2011-10-23T08:52:33.027 に答える