プロットを新しいデータで更新したいとします。どの方法を選ぶべきですか?
- プロパティをある名前に設定し
XDataSource
、変数を更新して、refreshdata
- 元のを消去して、コマンドを再
plot
呼び出ししてください。plot
- 使用する
Set('Xdata',...')
プロットを新しいデータで更新したいとします。どの方法を選ぶべきですか?
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つの関連する手段があります。
それでは、考えられる方法を分析しましょう。
Method(1)-refreshdata
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
通過する2つの醜い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
、そしてそれがどのように使用されるかを理解するための演習として残しています。)
関連するプロットを引数として指定した場合でも、2番目のループがあります。これはeval
数回実行されます。正確には効率的ではありません。最後に時間比較を示します。
結論:理解しにくい、リファクタリングしにくい、実行時間が遅い
方法(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秒です。
プロットを新しいデータで更新したいとします。どの方法を選択すればよいですか?
指定された軸に複数の線オブジェクトがある場合、メソッド:
- XDataSource プロパティを何らかの名前に設定し、変数を更新して呼び出します
refreshdata
MATLAB R2012b でエラーが発生します。Andrey's answer に適切な例が示されています。
バグが Mathworks に提出されました。