funcion español matlab figures

español - subplot matlab



MATLAB: ¿la mejor manera de actualizar dinámicamente una línea maneja ''XData e YData? (3)

Parte del motivo por el que su código puede tardar mucho tiempo en ejecutarse es porque está utilizando un bucle for para asignar sus variables. Dependiendo de la versión de Matlab que esté utilizando, esto reducirá significativamente su proceso. Sugiero usar la vectorización para asignar valores a tu x y y así:

x = 1:1000; y = cosd(x);

A continuación, puede asignar los primeros puntos en sus datos.

xi = x(1); yi = y(1);

Cuando trace, asigne XDataSource e YDataSource.

h = plot(xi, yi, ''YDataSource'', ''yi'', ''XDataSource'', ''xi'');

Ahora cuando realiza un bucle para cambiar los valores, use los datos de actualización para actualizar los valores de Xdata e Ydata. Use la función drawow para actualizar la ventana de figura.

for k = 2:1000, xi = x(1:k); yi = y(1:k); refreshdata(h, ''caller'') drawnow; end

Estoy recopilando datos y trazando esos datos en tiempo real. Los datos son producidos por un sistema de captura de movimiento. Tengo una clase DynamicDataset que es solo un contenedor alrededor de una matriz de dos columnas (aunque es más matizada que eso) con un notificador de eventos para nuevos datos agregados; otra clase DynamicPlotter que escucha el evento de datos agregados y actualiza la trama de forma dinámica. Recortes de código apropiados:

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

Basado en el perfil de código MATLAB, el comando set en updatePlot() es bastante caro. Me pregunto si hay una mejor manera de trazar puntos individuales a medida que se presenten. Idealmente, insertaría el único punto en XData e YData y dibujaría ese punto solamente, pero no sé si esto es posible.

Tenga en cuenta que puede haber múltiples objetos lineeries (es decir, múltiples gráficos en la misma parcela); plot() toma un asa de ejes como argumento, por lo que no tendría en cuenta las propiedades de los tiradores de línea dibujados previamente (¿o hay alguna forma de hacerlo?); Pensé en hacer una plot(x,y);hold all; pero eso me daría identificadores de línea separados cada vez, cada uno correspondiente a un solo punto.

Puede ser que no haya forma de hacer que trazar los puntos entrantes sea más rápido, pero pensé que lo haría.

EDITAR : OP actualizado con el código real con el que estoy trabajando, en lugar de usar un ejemplo genérico que está mal interpretado.


La cantidad de datos que maneja en cada actualización es grande (aunque solo un punto en realidad está cambiando), lo que hace que su código sea O (N ^ 2).

Al usar una segunda línea de líneas para crear un gran grupo de datos, puede alternar entre agregar cada punto a una línea "activa" corta y agregar bloques grandes de forma infrecuente a las líneas principales. Si bien esto no evita exactamente O (N ^ 2), le permite reducir la constante de manera significativa.

Si hace esto, recuerde superponer las lineeries "viejas" y lineeries "activas" en un punto, para que se conecten.

Esencialmente:

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


Su código es lento, porque está repitiendo todos los valores cada vez que llama a updatePlot . Por lo tanto, solo trazaré el último punto en updatePlot (Este es también el problema que has planteado: idealmente insertaría el punto único en XData e YData y solo sacaré ese punto, pero no sé si esto es posible. )

  1. agregar propiedad LH_point_counter

    classdef DynamicPlotter < dynamicprops properties FH %# figure handle AH %# axes handle LH %# cell array of line handles - may have multiple lines on the plot % counter that counts home many points we have for each dynProps LH_point_counter = []; dynProps = {} %# cell array of dynamic property names - %# use to access individual datasets end

  2. modificar updatePlot

    function updatePlot(obj, propNum) % plot new point new_x = obj.(dynProps{propNum}).newestData(1); new_y = obj.(dynProps{propNum}).newestData(2); new_handle = plot(new_x, new_y); % add new handle to list of handles of this property counter_this_prop = obj.LH_point_counter(propNum); counter_this_prop = counter_this_prop + 1; obj.LH{propNum}(counter_this_prop) = new_handle; % save new counter value obj.LH_point_counter(propNum) = counter_this_prop; end