MATLAB-动态更新行句柄的XData和YData的最佳方法? [英] MATLAB - best way to dynamically update a line handles' XData and YData?

查看:205
本文介绍了MATLAB-动态更新行句柄的XData和YData的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在收集数据并实时绘制该数据.数据由运动捕捉系统生成.我有一个类DynamicDataset,它只是一个2列矩阵的包装器(尽管比它更细微),并带有一个事件通知器,用于添加新数据.另一个类DynamicPlotter,它侦听添加了数据的事件并动态更新绘图.适当的代码段:

I am collecting data and plotting that data in real time. The data are produced by a motion capture system. I have one class DynamicDataset that is just a wrapper around a 2-column matrix (although it's more nuanced than that) with an event notifier for new data added; another class DynamicPlotter that listens for the data-added event and updates the plot dynamically. Appropriate code snippets:

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

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

Based on the MATLAB Code Profile, the set command in updatePlot() is rather expensive. I am wondering if there is a better way to plot individual points as they come? Ideally I would push the single point into XData and YData and draw that point only, but I don't know if this is possible.

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

Please note that there may be multiple lineseries objects (i.e., multiple graphs on the same plot); plot() takes an axes handle as an argument, so it wouldn't consider the properties of the previously drawn line handles (or is there a way to make it do so?); I thought of just doing plot(x,y);hold all; but that would give me separate line handles every time, each corresponding to a single point.

可能无法更快地绘制输入点,但我想我会问.

It might be that there's no way to make plotting incoming points any faster, but I figured I'd ask.

编辑:使用我正在使用的实际代码更新了OP,而不是使用了容易引起误解的通用示例.

EDIT: Updated OP with actual code I'm working with, rather than using a generic example that's up for misinterpretation.

推荐答案

每次更新中要处理的数据量很大(尽管实际上只有一个点在更改),这会使代码O(N ^ 2 ).

The amount of data you're handling in each update, is large (although only a single point is actually changing), making your code O(N^2).

通过使用第二个线系列来构建大量数据,您可以在将每个点添加到短的活动"线之间以及不频繁地在主线系列中添加大块之间进行切换.虽然这不能完全避免O(N ^ 2),但可以让您显着减小常数.

By using a second lineseries to build up a large group of data, you can alternate between adding every point to a short "active" line, and infrequently adding large blocks to the main lineseries. While this doesn't exactly avoid O(N^2), it lets you reduce the constant significantly.

如果这样做,请记住将旧"线系列和活动"线系列重叠一点,以便它们连接.

If you do this, remember to overlap the "old" lineseries and "active" lineseries by one point, so that they connect.

本质上:

    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

这篇关于MATLAB-动态更新行句柄的XData和YData的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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