MATLAB - 动态更新线的最佳方法是处理'XData和YData?

Dan*_*hoa 6 matlab figures

我正在收集数据并实时绘制数据.数据由运动捕捉系统产生.我有一个类DynamicDataset只是一个2列矩阵的包装器(虽然它比那更细致),并且添加了新数据的事件通知器; 另一个类DynamicPlotter,它监听数据添加事件并动态更新绘图.适当的代码段:

classdef DynamicDataset < handle
    properties
        newestData = [];
        data = []
    end
    events
        DataAdded
    end
    methods
        function append(obj, val)
            obj.data(end+1,:) = val;
            obj.newestData = val;
            notify(obj, 'DataAdded');
        end
    end
end

classdef DynamicPlotter < dynamicprops
    properties
        FH %# figure handle
        AH %# axes handle
        LH %# array of line handles - may have multiple lines on the plot

        dynProps = {} %# cell array of dynamic property names - 
                      %# use to access individual datasets
    end
    methods
        function obj = DynamicPlotter(props) %# props is a cell array of dynamic 
                                             %# properties to store information
            for i = 1:length(props) 
                addprop(obj, props{i});
                obj.(props{i}) = DynamicDataset;
                obj.dynProps = [obj.dynProps props{i}];

                addlistener(obj.(props{i}), 'DataAdded', @obj.updatePlot(i));
            end
            obj.createBlankPlot();
        end

        function createBlankPlot(obj)
            obj.FH = figure;
            obj.AH = axes;

            hold all;

            for i = 1:length(obj.dynProps)
                obj.LH(i) = plot(nan); %# only used to produce a line handle
                    set(obj.LH(i), 'XData', [], 'YData', []);
            end
        end

        function updatePlot(obj, propNum)
            X = get(obj.LH(propNum), 'XData');
            Y = get(obj.LH(propNum), 'YData');

            X(end+1) = obj.(dynProps{propNum}).newestData(1);
            Y(end+1) = obj.(dynProps{propNum}).newestData(2);

            set(obj.LH(propNum), 'XData', X, 'YData', Y);
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

基于MATLAB代码配置文件,set命令输入updatePlot()相当昂贵.我想知道是否有更好的方法来绘制个别积分?理想情况下,我会将单点推入XDataYData仅绘制该点,但我不知道这是否可行.

请注意,可能有多个lineseries对象(即同一图上的多个图表); plot()将一个轴句柄作为参数,因此它不会考虑先前绘制的线句柄的属性(或者有没有办法让它这样做?); 我只是想做,plot(x,y);hold all;但每次都会给我单独的线句,每个句柄对应一个点.

可能是因为没有办法更快地绘制输入点,但我想我会问.

编辑:使用我正在使用的实际代码更新了OP,而不是使用一个错误解释的通用示例.

Ben*_*igt 4

您在每次更新中处理的数据量很大(尽管实际上只有一个点发生变化),使您的代码复杂度为 O(N^2)。

通过使用第二个线系列来构建大量数据,您可以交替将每个点添加到短“活动”线,以及不频繁地将大块添加到主线系列。虽然这并不能完全避免 O(N^2),但它可以让您显着减少常数。

如果执行此操作,请记住将“旧”线系列和“活动”线系列重叠一点,以便它们连接。

本质上:

    function updatePlot(obj, propNum)
        X = get(obj.LHactive(propNum), 'XData');
        Y = get(obj.LHactive(propNum), 'YData');

        X(end+1) = obj.(dynProps{propNum}).newestData(1);
        Y(end+1) = obj.(dynProps{propNum}).newestData(2);

        if numel(X) > 100
            Xold = [get(obj.LH(propNum), 'XData'); X(2:end)];
            Yold = [get(obj.LH(propNum), 'YData'); Y(2:end)];
            set(obj.LH(propNum), 'XData', Xold, 'YData', Yold);

            X = X(end);
            Y = Y(end);
        end

        set(obj.LHactive(propNum), 'XData', X, 'YData', Y);
    end
Run Code Online (Sandbox Code Playgroud)