Zbieram dane i kreślę te dane w czasie rzeczywistym. Dane są produkowane przez system przechwytywania ruchu. Mam jedną klasę DynamicDataset
, która jest po prostu opakowaniem wokół matrycy 2-kolumnowej (chociaż jest bardziej zniuansowana) z powiadomieniem o zdarzeniu dla nowych dodanych danych; inna klasa DynamicPlotter
, która nasłuchuje zdarzenia dodanego do danych i dynamicznie aktualizuje wykres. Odpowiednie fragmenty kodu:MATLAB - najlepszy sposób dynamicznej aktualizacji linii obsługuje "XData i YData?
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
oparciu o profil Kod MATLAB, polecenie w updatePlot()
set
jest raczej drogie. Zastanawiam się, czy istnieje lepszy sposób na wytypowanie poszczególnych punktów, gdy nadejdą? Najlepiej byłoby przesłać pojedynczy punkt do XData
i YData
i narysować tylko ten punkt, ale nie wiem, czy to możliwe.
Należy pamiętać, że może istnieć wiele obiektów lineserii (tj. Wiele wykresów na tym samym wykresie); plot()
przyjmuje argument osi, jako argument, więc nie bierze pod uwagę właściwości wcześniej narysowanych linii (lub czy istnieje sposób, aby to zrobić?); Myślałem o zrobieniu plot(x,y);hold all;
, ale to dałoby mi osobne linie za każdym razem, z których każdy odpowiadałby jednemu punktowi.
Może to być tak, że nie da się przyspieszyć wykreślania punktów, ale pomyślałem, że zapytam.
EDIT: Zaktualizowałem OP za pomocą kodu, nad którym pracuję, zamiast używać ogólnego przykładu, który jest źle interpretowany.
Nie wiem czy widzieliście to jednak przyjrzeć http://stackoverflow.com/questions/1693429/matlab-oop-is-it-slow-or-am- I-doing-something-wrong. Zasadniczo korzystanie z klas w Matlab generalnie skutkuje słabą wydajnością – Marm0t
dzięki, widziałem to już wcześniej. Mój projekt wymaga użycia klas z powodów, dla których nie wejdę, więc nie ma na to żadnego sposobu, ale czy wywołanie 'set' będzie powolne, ponieważ jest wywoływane wewnątrz metody? –
@ strictlyrude27: powinieneś poprawić linię addlistener jako: 'addlistener (obj. (Props {i}), 'DataAdded', @ (src, ev) obj.updatePlot (i));'. Możesz również chcieć dodać 'drawnow' na końcu funkcji' updatePlot' – Amro