为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Matlab中更新绘图数据?

如何在Matlab中更新绘图数据?

胡子哥哥 2019-12-27 10:11:52
假设我想用新数据更新绘图。我应该选择哪种方法?将XDataSource属性设置为某些名称,更新变量,然后调用refreshdata删除原稿plot,然后plot再次调用命令。采用 Set('Xdata',...')
查看完整描述

3 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

简短的回答:经常使用 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

长答案:


有三种相关措施可供选择一种最佳方法。


代码清晰 -有人阅读您的代码有多容易?

运行时 -每种方法执行任务的速度有多快?

代码可移植性 -您重构代码的速度有多快?

现在,让我们分析可能的方法。


方法(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源代码,您会注意到两个丑陋的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

假设您没有一个图,但是有100个图,而您只想更新第一个图。这将非常慢,因为对于每个图,您都会尝试找到所需的图!(我将作为练习供读者弄清楚是什么ecruoSataD,以及如何使用它。)


即使将相关的图作为参数,您仍然会有第二个循环,该循环运行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

这种方法对读者来说很清楚。您删除了该图,并绘制了一个新图。但是,从最后的时间比较中可以看出,这是最慢的方法。


结论:易于理解,易于重构,运行速度非常慢


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


代码真的很清楚。您想要修改绘图的两个属性,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秒。


查看完整回答
反对 回复 2019-12-27
?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

您可以调用该函数drawnow并执行类似的操作:


h = plot(nan);


for i = 1:n

  y = ...

  set(h,'YData',y);

  drawnow                 %update the graph

end


查看完整回答
反对 回复 2019-12-27
?
jeck猫

TA贡献1909条经验 获得超7个赞

假设我想用新数据更新绘图。我应该选择哪种方法?

如果给定轴上有多个线对象,则方法:

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

将在MATLAB R2012b中生成错误。Andrey的答案中提供了一个适当的示例。

已将一个错误提交给Mathworks。


查看完整回答
反对 回复 2019-12-27
  • 3 回答
  • 0 关注
  • 1129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信