best way to dynamically update a line handles' XData and YData?

조회 수: 29 (최근 30일)
Clayton Chu
Clayton Chu 2011년 9월 16일
댓글: Nick Gallo 2020년 1월 22일
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.(names{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
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.
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.
  댓글 수: 2
Patrick Kalita
Patrick Kalita 2011년 9월 16일
Do you know which line of updatePlot() takes the most time? Is it the call to SET? Is it the data appending in the two lines before that?
Clayton Chu
Clayton Chu 2011년 9월 16일
@Patrick - it's definitely the SET call.

댓글을 달려면 로그인하십시오.

답변 (2개)

Steven Lord
Steven Lord 2016년 5월 17일
For the benefit of the original poster (if they reread a nearly 5 year old message) or others who have the same general question, consider if an animatedline will do what you need/want.

Kevin Claytor
Kevin Claytor 2016년 5월 17일
Using the HG2 dot notation may speed things up enough for you (see handle class properties );
function updatePlot(obj, propNum)
lh = obj.LH(propNum);
new_x = obj.(dynProps{propNum}).newestData(1);
new_y = obj.(dynProps{propNum}).newestData(2);
lh.XData = [lh.XData, new_x];
lh.YData = [lh.YData, new_y];
end
If it does speed things up for you, I'd be curious how much, I've not yet done a side-by-side comparison.

카테고리

Help CenterFile Exchange에서 Graphics Performance에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by