我应该如何更新Matlab中绘图的数据? [英] How should I update the data of a plot in Matlab?

查看:2396
本文介绍了我应该如何更新Matlab中绘图的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想用新数据更新一个绘图。我应该选择什么方法?


  1. XDataSource 属性设置为某个名称,更新变量,然后调用 refreshdata

  2. 清除原始,然后调用 plot 命令。

  3. 使用 Set('Xdata',...')


解决方案

简短回答:总是使用 Set('Xdata',...')



示例代码:

 函数PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x。^ 3);
set(h,'XData',x,'YData',y);
end








有三种相关的方法可供您选择最佳方法。


  1. 代码清晰度 - 某人阅读代码的容易程度如何?

  2. 运行时间方法执行其任务?

  3. 代码可移植性 - 您可以以多快的速度重新计算代码?

现在我们来分析一下可能的方法。

方法(1) - refreshdata

 函数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)

 赋给变量`y`的值可能是未使用的

为什么会发生? refreshdata 使用 eval m-lint 无法知道您将使用 y 。有人读你的代码,不妨完全删除这一行。这是因为你打破了封装原则。 refreshdata 访问调用者工作区中的变量。另一种方法来看看这个,假设你将图的句柄传递给另一个函数。读者不知道为什么你写了 y = sin(x。^ 3); ,以及它如何与更新图相关。

现在我们来讨论速度/运行时间。通过查看 refreshdata 源代码,您会注意到两个丑陋的for循环,它们贯穿了您的空间中图形句柄变量的所有 。这是第一个:

 %收集所有对象以刷新
objs = {};
for k = 1:length(h)
obj = h(k);
objfields = fields(obj);
for k2 = 1:length(objfields)
%搜索以DataSource结尾的属性
如果strncmpi(fliplr(objfields {k2}),'ecruoSataD',10)
objs = {objs {:},obj,objfields {k2}};
end
end
end

想象一下你没有一个情节,但100个情节,你只想更新第一个。这将非常缓慢,因为对于每个地块,您都试图找到您需要的一个! (我正在做一个练习,让读者了解 ecruoSataD 是什么,以及它是如何使用的。)



<即使您将相关图表作为参数,您仍然有第二个循环,它会多次运行 eval 。不完全有效。结束语:很难理解,难以重构,运行时间较慢





方法(2) - 删除并重绘

 函数PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
set(h,'YDataSource','y')
set(h,'XDataSource','x')
y = sin(x。^ 3);
删除(h);
h = plot(x,y);
end

这个方法对读者来说非常清楚。你删除了情节,并画了一个新的。但是,从最后的时间比较中我们会看到,这是最慢的方法。
$ b

结论:容易理解,易于重构,运行时间非常缓慢。


$ b

方法(3) - set('XData',...,'YData')

<代码非常清晰。你想修改你的情节的两个属性, XData YData 。这正是你所做的。另外,代码的运行速度非常快,您可以从下面的比较中看到。

 函数PlotUpdate()
x = 0:0.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x。^ 3);
set(h,'XData',x,'YData',y);
end

由于新的图形引擎hg2(R2014b及以上),您也可以使用属性语法用于指定数据,如果您喜欢这种表示法:

 函数PlotUpdate()
x = 0:.1:8 ;
y = sin(x);
h = plot(x,y);
y = sin(x。^ 3);
h.XData = x;
h.YData = y;
end

结论:易于理解,易于重构, / em>






以下是时间比较代码

 函数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秒。



Suppose that I want to update a plot with a new data. What method should I choose?

  1. Set the XDataSource property to some name, update the variable, and call refreshdata
  2. Erase the original plot, and call plot command again.
  3. Use Set('Xdata',...')

解决方案

Short answer : always use Set('Xdata',...').

Example code:

function PlotUpdate()   
    x = 0:.1:8;
    y = sin(x);
    h = plot(x,y);
    y = sin(x.^3);    
    set(h,'XData',x,'YData',y);
end


Long answer:

There are three relevant measures by which one should choose the best method.

  1. Code clarity - How easy it is for someone to read your code?
  2. Runtime - How quick each method performs its task?
  3. Code portability - How fast can you re-factor your code?

Now, let's analyze the possible methods.

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 immediately issues a warning in the line y=sin(x.^3)

The value assigned to variable `y` might be unused

Why does it happen? refreshdata uses eval and m-lint cannot know that you will use y. Someone reading your code, might as well remove this line completely. This happened because you broke the encapsulation principle. refreshdata accesses variables from the caller workspace. Another way to take a look at this, suppose that you pass the handle of the plot to another function. The reader has no clue to why on earth you wrote y = sin(x.^3);, and how is it going to be related to the update of the plot.

Now let's discuss speed/runtime. By taking a look at refreshdata source code, you will notice two ugly for-loops, that go through all of the graphics handles variables in your space. Here is the first:

% 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

Imagine that you have not one plot, but 100 plot and you want to update only the first. This will be very slow, because for each of the plots, you attempt to find the one you need! (I am leaving as an exercise for the reader to figure out what is ecruoSataD, and how it is used.)

Even if you give the relevant plot as an argument, you still have the second loop, that runs eval several times. Not exactly efficient. I will show a time comparison in the end.

Conclusion : Hard to understand, hard to refactor, slow runtime


Method (2) - Delete and re-plot

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

This method is quite clear for the reader. You deleted the plot, and drew a new one. However, as we will see from the time comparison in the end, that is the slowest method.

Conclusion : Easy to understand, easy to refactor, very slow runtime


Method(3) - set('XData',...,'YData')

The code is really clear. You want to modify a two properties of your plot, XData and YData. And that is exactly what you do. Also, the code runs really fast, as you can see from the comparison below.

function PlotUpdate()   
    x = 0:.1:8;
    y = sin(x);
    h = plot(x,y);
    y = sin(x.^3);          
    set(h,'XData',x,'YData',y);
end

Since the new graphics engine hg2 (R2014b and up), you can also use property syntax for specifying data if you prefer that notation:

function PlotUpdate()   
    x = 0:.1:8;
    y = sin(x);
    h = plot(x,y);
    y = sin(x.^3);          
    h.XData = x;
    h.YData = y;
end

Conclusion : Easy to understand, easy to refactor, fast runtime


Here is the time comparison code

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

And the results:

Elapsed time is 0.075515 seconds.
Elapsed time is 0.179954 seconds.
Elapsed time is 0.002820 seconds.

这篇关于我应该如何更新Matlab中绘图的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆