新しいデータでプロットを更新するとします。どの方法を選択すればよいですか?
XDataSource
プロパティに何らかの名前を設定し、変数を更新して、refreshdata
を呼び出しますplot
を消去し、plot
コマンドを再度呼び出します。Set('Xdata',...')
を使用します短い答え:常にSet('Xdata',...')
を使用します。
サンプルコード:
_function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x.^3);
set(h,'XData',x,'YData',y);
end
_
長答:
最適な方法を選択するための3つの関連する手段があります。
それでは、可能な方法を分析しましょう。
メソッド(1)-リフレッシュデータ
_function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
set(h,'YDataSource','y')
set(h,'XDataSource','x')
y = sin(x.^3);
refreshdata(h,'caller');
end
_
M-lintはすぐにy=sin(x.^3)
行で警告を発行します
_The value assigned to variable `y` might be unused
_
なぜ起こるのですか? refreshdata
はeval
を使用し、_m-lint
_はy
を使用することを認識できません。コードを読んでいる人は、この行を完全に削除することもできます。これは、カプセル化の原則を破ったために発生しました。 refreshdata
は、呼び出し元のワークスペースから変数にアクセスします。これを見る別の方法として、プロットのハンドルを別の関数に渡すと仮定します。読者は、いったいなぜあなたがy = sin(x.^3);
を書いたのか、そしてそれがプロットの更新とどのように関係するのかについての手掛かりを持っていません。
次に、速度/実行時間について説明します。 refreshdata
ソースコードを見ると、グラフィックハンドル変数のallを通過する2つのforいforループに気付くでしょう。あなたの空間で。これが最初です:
_% gather up all the objects to refresh
objs = {};
for k = 1:length(h)
obj = h(k);
objfields = fields(obj);
for k2 = 1:length(objfields)
% search for properties ending in DataSource
if strncmpi(fliplr(objfields{k2}),'ecruoSataD',10)
objs = {objs{:},obj, objfields{k2}};
end
end
end
_
1つのプロットではなく、100のプロットがあり、最初のプロットのみを更新したいとします。これは非常に遅くなります。なぜなら、プロットごとに、必要なプロットを見つけようとするからです! (読者がecruoSataD
とは何か、どのように使用されるかを理解するための演習として残しておきます。)
関連するプロットを引数として指定した場合でも、eval
を数回実行する2番目のループがあります。正確には効率的ではありません。最後に時間比較を示します。
結論:理解するのが難しく、リファクタリングするのが難しく、ランタイムが遅い
方法(2)-削除と再プロット
_function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
set(h,'YDataSource','y')
set(h,'XDataSource','x')
y = sin(x.^3);
delete(h);
h = plot(x,y);
end
_
この方法は、読者にとって非常に明確です。プロットを削除し、新しいプロットを描きました。ただし、最後の時間比較からわかるように、これが最も遅い方法です。
結論:理解しやすく、リファクタリングしやすく、実行時間が非常に遅い
Method(3)-set( 'XData'、...、 'YData')
コードは本当に明確です。プロットの2つのプロパティ、XData
およびYData
を変更します。それがまさにあなたがすることです。また、以下の比較からわかるように、コードは非常に高速に実行されます。
_function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x.^3);
set(h,'XData',x,'YData',y);
end
_
新しいグラフィックエンジンhg2(R2014b以降)以降、その表記法を希望する場合は、データを指定するプロパティ構文を使用することもできます。
_function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x.^3);
h.XData = x;
h.YData = y;
end
_
結論:理解しやすく、リファクタリングしやすく、ランタイムが速い
これが時間比較コードです
_function PlotUpdateTimeCompare()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
set(h,'YDataSource','y')
set(h,'XDataSource','x')
y = sin(x.^3);
tic
for i=1:100
refreshdata(h,'caller');
end
toc
tic
for i=1:100
delete(h);
h = plot(x,y);
end
toc
tic
for i=1:100
set(h,'XData',x,'YData',y);
end
toc
end
_
そして結果:
経過時間は0.075515秒です。
経過時間は0.179954秒です。
経過時間は0.002820秒です。
関数drawnow
を呼び出して、そのようなことを行うことができます。
h = plot(nan);
for i = 1:n
y = ...
set(h,'YData',y);
drawnow %update the graph
end
新しいデータでプロットを更新するとします。どの方法を選択すればよいですか?
指定された軸に複数のラインオブジェクトがある場合、メソッド:
- XDataSourceプロパティに名前を設定し、変数を更新して、
refreshdata
を呼び出します
mATLAB R2012bでエラーを生成します。適切な例は、Andreyの回答に記載されています。
バグがMathworksに提出されました。